#reactjs
#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?
Комментарии:
1. Не могли бы вы предоставить «код переноса» более подробно?
Ответ №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. Может быть, его условием является использование
state
, доступного только в дочернем компоненте?
Ответ №2:
Если вы думаете о том, как работает 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 amp;amp; 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
вы зайдете в тупик, поскольку его дочерние элементы больше никогда не будут оцениваться.