Creating web tools with React.
Is it possible to prevent the useEffect of the child components from igniting when the parent component changes to something else?
We have prepared the smallest sample.
CodeSandbox: https://codesandbox.io/s/jovial-kowalevski-lkdbx
functionComponentA(props){
return(
<div style={{backgroundColor:"pink"}}>
<p>Component A</p>
{props.children}
</div>
);
}
functionComponentB(props){
return(
<div style={{backgroundColor:"skyblue"}}>
<p>Component B</p>
{props.children}
</div>
);
}
functionCommonComponent(){
React.useEffect(()=>{
console.log("useEffect is running in CommonComponent.");
}, []);
return(<div>Common component.</div>);
}
functionApp(){
const [ab, setAB] = React.useState(true);
const ParentComponent=ab?ComponentA:ComponentB;
return(
<React.Fragment>
<label>
<input
type="checkbox"
checked = {ab}
onChange={(event)=>{
setAB(event.target.checked);
}}
/>
Switch A/B
</label>
<ParentComponent>
<CommonComponent/>
</ParentComponent>
</React.Fragment>
);
}
constrootElement= document.getElementById("root");
ReactDOM.render(
<React.StrictMode>
<App/>
</React.StrictMode>,
rootElement
);
.App{
font-family:sans-serif;
text-align:center;
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js">/script>
<divid="root"></div>
Each time you switch SSwitch A/B 」, the useEffect in CommonComponent fires, and the console prints とuseEffect is running in CommonComponent. "
At this time, the actual application fetches data from the server, which is expensive to execute.
Is it possible to avoid re-running useEffect in some way, as this useEffect is essentially unaffected by the parent, as you set an empty array in the dependency list?
Component A, B are actually forms, and CommonComponent is part of a form that summarizes several check boxes.
reactjs react-jsx
This may be a problem that has already been solved, but I will write an answer for your reference only.
If the parent component is re-rendered, the child component will always be re-rendered, so if the structure cannot be changed to a sibling component, the code will be difficult.
This time, we don't want to prevent re-rendering, but we want to run a heavy fetch only once, so there is also a way to deploy a state management library such as Redux
However, in this case, only the information in the questionnaire is
So, isn't this useEffect
supposed to be the responsibility of App
?
If so, you can define the useCommonStatus()
of your own hook as follows, render ParentComponent
and CommonComponent
with the responsibility component (App
) to pass useEffect
to fetch.
Create Your Own Hook – React
https://ja.reactjs.org/docs/hooks-custom.html
//proprietary hook
function useCommonStatus(){
const [common, setCommon] = React.useState (null);
React.useEffect(()=>{
console.log("useEffect is running.");
setTimeout(()=>{
console.log("useEffect completed.");
setCommon ([1, 2, 3, 4, 5]);
}, 5000);
}, []);
return common;
}
functionComponentA(props){
return(
<div style={{backgroundColor:"pink"}}>
<p>Component A</p>
{props.children}
</div>
);
}
functionComponentB(props){
return(
<div style={{backgroundColor:"skyblue"}}>
<p>Component B</p>
{props.children}
</div>
);
}
functionCommonComponent (props) {
return(<div>Common component values: {props.common?props.common.join(): 'Loading...'}</div>);
}
functionApp(){
const common=useCommonStatus();
const [ab, setAB] = React.useState(true);
const ParentComponent=ab?ComponentA:ComponentB;
return(
<React.Fragment>
<label>
<input
type="checkbox"
checked = {ab}
onChange={(event)=>{
setAB(event.target.checked);
}}
/>
Switch A/B
</label>
<ParentComponent>
<CommonComponent common={common}/>
</ParentComponent>
</React.Fragment>
);
}
constrootElement= document.getElementById("root");
ReactDOM.render(
<React.StrictMode>
<App/>
</React.StrictMode>,
rootElement
);
.App{
font-family:sans-serif;
text-align:center;
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js">/script>
<divid="root"></div>
© 2024 OneMinuteCode. All rights reserved.