Quiero pasar esta función de control a todos los elementos secundarios de mi componente Diseño. Sé cómo hacerlo en componentes personalizados, pero en children no puedo hacerlo funcionar.
Probé la solución desde aquí , pero sigo recibiendo esta advertencia:
Aquí está mi código:
function Layout({ preview, children }) { const [hovered, setHovered] = useState(false); function toggleHover() { setHovered(!hovered); } const childrenWithProps = React.Children.map(children, (child) => { if (React.isValidElement(child)) { return React.cloneElement(child, { toggleHover }); } return child; }); return ( <> <Mouse hovered={hovered} /> <div> <Navbar toggleHover={toggleHover} /> <main>{childrenWithProps}</main> <Footer toggleHover={toggleHover} /> </div> </> ); } export default Layout; function Mouse({hovered}) { return null; }; function Navbar({toggleHover}) { return <div onMouseEnter={toggleHover}>Hover on me</div> }; function Footer({toggleHover}) { return <div onMouseEnter={toggleHover}>Hover on me</div> }; function Child({toggleHover}) { return <div onMouseEnter={toggleHover}>I am child, hover on me</div> }; function Layout({ preview, children }) { const [hovered, setHovered] = React.useState(false); function toggleHover() { console.log("hovered"); setHovered(!hovered); } const childrenWithProps = React.Children.map(children, (child) => { if (React.isValidElement(child)) { return React.cloneElement(child, { toggleHover: toggleHover }); } return child; }); return ( <div> <Mouse hovered={hovered} /> <div> <Navbar toggleHover={toggleHover} /> <main>{childrenWithProps}</main> <Footer toggleHover={toggleHover} /> </div> </div> ); } function Parent() { return ( <div> <Layout> <Child /> <Child /> <Child /> </Layout> </div> ) } const rootElement = document.getElementById("root"); ReactDOM.render( <Parent />, rootElement ); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script> <body> <div id="root"></div> </body> El problema está en la función childrenWithProps , especialmente en el argumento de accesorios React.cloneElement . En su ejemplo, está utilizando el valor toggleHover que esencialmente se transforma en toggleHover: toggleHover .
Para que funcione, debe transformar los accesorios pasados en esto: children_prop_name: toggleHover .
Un ejemplo más detallado:
Función que maneja las propiedades de los niños:
const childrenWithProps = React.Children.map(children, (child) => { if (React.isValidElement(child)) { return React.cloneElement(child, { toggleProp: toggleHover }); } return child; });Un componente hijo:
function Child({toggleProp}) { return <div onHover={toggleProp}>Click</div> }