如何向作为Container子元素传入的React组件传递内部回调函数?
首先先修正你原有Container代码中的两处问题:
- 重复声明
setSelection变量,自定义函数和useState返回的状态更新函数重名,会触发运行时报错 - 状态更新时直接引用外层
selection变量存在闭包陷阱,多次调用会出现状态更新异常,改用更新回调的入参prev获取最新状态即可。
方案1:自动遍历子组件注入callback(调用侧写法简洁)
借助React原生的React.Children.map和React.cloneElement能力,在Container内部遍历所有直接子组件,自动注入callback属性,调用时无需手动传参。
修改后的Container代码:
import { useState, Children, cloneElement } from 'react'; const Container = ({children}) => { const [selection, setSelection] = useState([]); const handleAddSelection = (returnObject) => { setSelection(prev => [...prev, returnObject]) } // 遍历子组件注入callback const processedChildren = Children.map(children, child => { // 仅给React组件类型注入,过滤文本、原生DOM节点等 if (typeof child?.type === 'function') { return cloneElement(child, { callback: handleAddSelection }) } return child }) return( <StyledContainer> {processedChildren} <Button>Search {selection}</Button> </StyledContainer> ) }
调用方式:
<Container><Child1 /></Container> <Container><Child2 /></Container>
注意:该方案仅支持给Container的直接子组件注入属性,如果子组件外层有div等其他元素包裹,自动注入会失效。
方案2:Render Props模式(灵活度更高,适配复杂场景)
如果子组件的回调属性名不统一,或者子组件不是直接子元素,优先用这种方案,将Container的children作为函数执行,把内部方法暴露给调用侧自行绑定。
修改后的Container代码:
import { useState } from 'react'; const Container = ({children}) => { const [selection, setSelection] = useState([]); const handleAddSelection = (returnObject) => { setSelection(prev => [...prev, returnObject]) } return( <StyledContainer> {/* 执行children函数暴露内部方法 */} {children(handleAddSelection)} <Button>Search {selection}</Button> </StyledContainer> ) }
调用方式:
{/* 适配callback属性名的子组件 */} <Container> {(handleAddSelection) => <Child1 callback={handleAddSelection} />} </Container> {/* 也适配其他回调属性名的子组件 */} <Container> {(handleAddSelection) => <CustomChild onSelect={handleAddSelection} />} </Container> {/* 嵌套场景也支持 */} <Container> {(handleAddSelection) => ( <div className="wrapper"> <Child2 callback={handleAddSelection} /> <Child3 callback={handleAddSelection} /> </div> )} </Container>
两种方案均为React原生能力,不需要引入Redux等外部状态管理库。
内容的提问来源于stack exchange,提问作者Alyona
相关产品推荐
相关产品推荐

