根据子组件有条件地呈现包装代码

时间:2020-08-25 05:50:08

标签: reactjs

const Components = {
  FirstComponent,
  SecondComponent,
  ThirdComponent,
};

//This is component A (parent)
// componentType is a prop

let TimelineContentComponent = Components[componentType];

<TimelineItem>
   <TimelineSeparator>
     <TimelineDot>
       <some content>
     </TimelineDot>
     <TimelineConnector />
   </TimelineSeparator>
   <TimelineContent>
     <TimelineContentComponent />
   </TimelineContent>
</TimelineItem>

//This is FirstComponent

if (<some condition C1 is true>) {
  return null;
}
<div>
  <!-- some code -->
</div>

//This is SecondComponent

if (<some condition C2 is true>) {
  return null;
}
<div>
  <!-- some code -->
</div>

//This is ThirdComponent

if (<some condition C3 is true>) {
  return null;
}
<div>
  <!-- some code -->
</div>

如您所见,子组件可能会渲染为null,在这种情况下,我根本不想渲染<TimelineItem>

另外,条件C1,C2和C3不同,条件逻辑由子组件知道,我不想将此逻辑移至父组件。

使用React实现此目标的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

为什么不也使用相同的条件变量来有条件地渲染组件A。

//这是组件A(父级)

if(<somecondition is true>){
return (
    <TimelineItem>
       <TimelineSeparator>
         <TimelineDot>
           <some content>
         </TimelineDot>
         <TimelineConnector />
       </TimelineSeparator>
       <TimelineContent>
         <B />
       </TimelineContent>
    </TimelineItem>
    )
    else return (
<div>something else</div>
   }

答案 1 :(得分:0)

如果考虑React的工作原理,这有点自相矛盾。

仅在渲染父级后才渲染子级。因此,父项不能依赖其子项进行渲染,因为在评估子项时,父项已经进行了渲染!

因此,为了控制父级,您需要事先了解各种条件C1,C2等。您需要将这些条件提升为共享状态。


const Parent = () => {
  const [ state, setState ] = useState({
   child1: true,
   child2: true,
   ...
  })
  
  const handleConditionChange = (child, condition) => { 
    setState(state => ({
      ...state,
      [child]: condition
    })
  }

  const [ forceRender, setForceRender ] = useState(true);
  useEffect(()=>{
    if (...) setForceRender(true) // you need to check this periodically in SOME WAY
  })

  // just an example of how you can use the children state to conditionally render the parent
  if ( forceRender || (state.child1 && state.child2 ...)) {
    return ( 
    ...
     <Child1 handleConditionChange={handleConditionChange}/>
     <Child2 handleConditionChange={handleConditionChange}/>
    ...
    ) 
  } else return null
}

const Child1 = (props) => {
  const [ condition, setCondition ] = useState() // controls if component renders or not

  useEffect(()=>{
    setCondition(<some condition>) // your boolean logic goes here
  })

  useEffect(()=>{
    props.handleConditionChange('child1', condition) // when condition changes, tell the parent
  },[condition])

  return condition 
    ? <component code>
    : null
}

这样,您仍然将逻辑保留在每个子组件中,但是现在您要向父报告,以便它也利用该信息。

编辑:添加了重置条件forceRender。您需要定期进行某种复位状态,否则,在Parent第一次返回null之后,您将陷入死胡同,因为其子级将不再被评估。