怎么实现子组件控制渲染父组件
- 在子组件控制父组件的state值【直接状态设置函数或者回调函数】
* 这个可以理解父组件向子组件传递了一个函数 - 直接是状态设置函数 *
function Parent (){
const [parentData,setParentData] = useState(false)
return (<>
{
parentData ? <div>状态为true,需要显示父级</div> : null
}
<Child setParentData={setParentData} />
</>)
}
function Child ({setParentData}){
function handleClick(){
setParentData(true)
}
return <div onClick={handleClick}>{'this is childData'}</div>
}
* 这个可以理解父组件向子组件传递了一个函数 - 回调函数形式处理 *
function Parent (){
const [parentData,setParentData] = useState(false)
function handleOnChildCallback(){
setParentData(true)
}
return (<>
{
parentData ? <div>状态为true,需要显示父级</div> : null
}
<Child onChildCallback={handleOnChildCallback} />
</>)
}
function Child ({onChildCallback}){
function handleClick(){
onChildCallback()
}
return (
<div onClick={handleClick}>{'this is childData'}</div>
)
}
- 在子组件直接绘制父组件需要的DOM
- antdesign Modal 为什么能在子组件直接设置modal的显示很隐藏的state基本和这一个思想
* 这个可以理解父组件向子组件传递了一个函数,函数设置的状态,【而该状态就是DOM片段】 - 直接是状态设置函数 *
* 因为万物皆可为state,那么DOM片段同样可以为State,那么这种情况就成为了可能 *
* 不过这里有几点值得思考:设置为DOM,整个组件树都要重新渲染,可以考虑子组件Memo *
function Parent (){
const [parentData,setParentData] = useState(null)
return (
<>
<div>显示父级相关DOM {parentData} </div>
<Child setParentData={setParentData} />
</>
)
}
function Child ({setParentData}){
const [childData,setChildData] = useState('this is childData')
useEffect(()=>{
setParentData && setParentData(<div>{childData}</div>)
},[childData,setParentData])
return <div>{'this is childData'}</div>
}
* 这个可以理解也是父组件向子组件传递了一个函数,函数返回的状态就是DOM片段 - 直接设置函数 *
* 不过这里有几点值得思考:
1、设置为DOM,整个组件树都要重新渲染,可以考虑子组件Memo
2、设置函数在父组件拿到回调以后再在父组件设置状态,不是向上面一种直接在子组件设置父组件状态
*
function Parent (){
const [parentData,setParentData] = useState(null)
const handleRenderContent = useCallback((childCallbackData) => {
setParentData(childCallbackData);
return () => {
setParentData(() => null);
};
}, []);
return (
<>
<div>显示父级相关DOM {parentData} </div>
<Child renderContent={handleRenderContent} />
</>
)
}
function Child ({renderContent}){
const [childData,setChildData] = useState('this is childData')
useEffect(() => {
if(renderContent){
return renderContent(() => {
return (
<div>
结合child的数据展现当前child时需要展示的数据
<span>{childData}</span>
</div>
);
});
}
}, [renderContent,childData]);
return <div>{'this is childData'}</div>
}
- 另外还可以借助:context,redux,发布订阅。。。等实现,本文不在枚举。