React HOC functional component: How to make any children have Parent's state and logic

1k Views Asked by At

I am trying to create a React function Hover component (link to a sandbox) which will give any of its {children} hover behaviors i.e. its internal hooks and methods:

function WithHover({ children }) {
  const [hover, setIsHover] = React.useState(null);
  const [hoverText, setHoverText] = React.useState("");
  const mouseOver = () => setIsHover((hover) => true);
  const mouseOut = () => setIsHover((hover) => false);

  const childrenWithExtraProp = React.Children.map(children, (child) => {
    return React.cloneElement(child, {
      hover,
      setIsHover,
      hoverText,
      setHoverText
    });
  });

  return (
    <>
      <div
        style={{
          width: "20%",
          height: "20",
          display: "block",
          marginBottom: "5%",
          backGroundColor: "pink"
        }}
      >
        <p>{hoverText}</p>
      </div>

      <main onMouseOver={mouseOver} onMouseOut={mouseOut}>
        {childrenWithExtraProp}
      </main>
    </>
  );
}

export default function App() {

  function Button({ children }) {
    return <button>{children}</button>;
  }
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>

      <WithHover />
      <Button hover={true}>foo</Button>
      <WithHover />
    </div>
  );
}

However when I checkin the <Button/> to see if the props were there via a console, I got a empty array?

function Button(props) { console.log('props', props); // zero props return {props.children}; }

What am I missing?

2

There are 2 best solutions below

0
On

You not actually using the children prop (it always nullish) since you closing the tag <WithHover/>.

Instead, try:

<WithHover>
  <Button>foo</Button>
</WithHover>

Edit romantic-allen-fl31f

0
On

You are closing the WithHover tag the wrong way and see the error is displayed on the screen as well. It is clearly showing you the way to resolve this issue by pointing out the error due to which it is failing. As Dennis Vash has mentioned in his answer the tag should be closed like:

<WithHover>
  <Button>foo</Button>
</WithHover>