Lab: implement scroller position with render props

import "./App.css";
import { useEffect, useState } from "react";

const MousePosition = ({ render }) => {
  const [mousePosition, setMousePosition] = useState({
    x: 0,
    y: 0,
  });

  useEffect(() => {
    const handleMousePositionChange = (e) => {
      // Use e.clientX and e.clientY to access the mouse position on the screen
      setMousePosition({
        x: e.clientX,
        y: e.clientY,
      });
    };

    window.addEventListener("mousemove", handleMousePositionChange);

    return () => {
      window.removeEventListener("mousemove", handleMousePositionChange);
    };
  }, []);

  // What should be returned here?
  return render(mousePosition);
};

// This component should not receive any props
const PanelMouseLogger = () => {
  return (
    <MousePosition
      render={(mousePosition) => (
        <div className="BasicTracker">
          <p>Mouse position:</p>
          <div className="Row">
            <span>x: {mousePosition.x}</span>
            <span>y: {mousePosition.y}</span>
          </div>
        </div>
      )}
    />
  );
};

// This component should not receive any props
const PointMouseLogger = () => {
  return (
    <MousePosition
      render={(mousePosition) => (
        <p>
          ({mousePosition.x}, {mousePosition.y})
        </p>
      )}
    />
  );
};

function App() {
  return (
    <div className="App">
      <header className="Header">Little Lemon Restaurant 🍕</header>
      <PanelMouseLogger />
      <PointMouseLogger />
    </div>
  );
}

export default App;

practice assignment

  1. problems with using custom hook to encapsulate cross-cutting data logic
    1. turns stateless component into a stateful one
    2. will have to alter implementation of each component that needs that specific data
  2. Valid vs. Invalid APIs for HOCs
    1. withSubscription(() => getData())(Component) - works
    2. withSubscription(Component, options) - works
    3. withSubscription(() => getData(), Component) - invalid
  3. best practices for HOCs
    1. pass unrelated props through to the wrapped component
    2. maximize composability using proper API definitions
  4. HOCs vs render props
    1. render props provides new data as function parameter, HOCs get new data as a new prop
    2. they inject new props into component to enhance them
  5. component with render prop as renderer cqn do anything a HOC can do

additional resources