React中如何在children prop传入的子组件中复用父组件状态并传事件
如何在通过
children传递子组件时实现子向父的事件传递? 当父组件通过children props接收未知子组件时,没法像常规场景那样直接给子组件传递回调props,这时候要实现点击子组件按钮触发父组件状态更新,有几种可行的方案:
方案1:用React.cloneElement克隆子组件并注入回调
React.cloneElement可以复制传入的子组件元素,同时给它添加额外的props,适合只有单个子组件的场景。
父组件代码:
import { useState, cloneElement } from 'react'; export default function Parent({ children }) { const [count, setCount] = useState(0); const handleClick = (num) => { setCount(current => current + num); }; // 克隆子组件,注入handleClick回调 const enhancedChild = cloneElement(children, { handleClick }); return ( <div> {enhancedChild} <h2>Count: {count}</h2> </div> ); }
子组件代码:
export default function Child({ handleClick }) { return ( <button onClick={() => handleClick(1)}> 点击加1 </button> ); }
使用方式:
<Parent> <Child /> </Parent>
方案2:渲染回调(Render Props)模式
把children改成一个函数,父组件将状态和回调作为参数传给这个函数,子组件通过调用函数来获取需要的props。这种方式更灵活,支持动态渲染子组件。
父组件代码:
import { useState } from 'react'; export default function Parent({ children }) { const [count, setCount] = useState(0); const handleClick = (num) => { setCount(current => current + num); }; // 调用children函数,传入需要的状态和回调 return ( <div> {children({ handleClick, count })} <h2>Count: {count}</h2> </div> ); }
使用方式:
<Parent> {({ handleClick }) => <Child handleClick={handleClick} />} </Parent>
方案3:使用React Context共享状态与回调
如果存在多层组件嵌套,或者多个子组件都需要触发父组件状态更新,用Context会更方便,不用逐层传递props。
步骤1:创建Context
import { createContext } from 'react'; export const CountContext = createContext();
步骤2:父组件作为Provider提供状态和回调
import { useState } from 'react'; import { CountContext } from './CountContext'; export default function Parent({ children }) { const [count, setCount] = useState(0); const handleClick = (num) => { setCount(current => current + num); }; return ( <CountContext.Provider value={{ count, handleClick }}> <div> {children} <h2>Count: {count}</h2> </div> </CountContext.Provider> ); }
步骤3:子组件通过useContext获取回调
import { useContext } from 'react'; import { CountContext } from './CountContext'; export default function Child() { const { handleClick } = useContext(CountContext); return ( <button onClick={() => handleClick(1)}> 点击加1 </button> ); }
使用方式:
<Parent> <Child /> </Parent>
内容的提问来源于stack exchange,提问作者user5618326
相关产品推荐
相关产品推荐

