What follows is a simple example:
const { Component } = React
const { render } = ReactDOM
const Label = ({ text }) => (
<p>{text}</p>
)
const Clock = ({ date }) => (
<div>{date.toLocaleTimeString()}</div>
)
class App extends Component {
constructor(props) {
super(props)
this.state = {
date: new Date()
}
}
componentDidMount() {
this.interval = setInterval(
() => this.setState({ date: new Date() }),
1000
)
}
componentWillUnmount() {
clearInterval(this.interval)
}
updateTime() {
}
render() {
return (
<div>
<Label text="The current time is:" />
<Clock date={this.state.date} />
</div>
)
}
}
render(<App />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
this.setState({ date: new Date() })
is being called every second updating the Clock with the current time. To my knowledge, setState
calls the render method on the App which causes the whole component to be rerendered including the Label.
Is there a way pass date to Clock (causing it to be rerendered) without rerendering the entirety of the App component? How big of a role does this play in regards to performance?
No, it will not re-render. If you pass any props to the component from the parent component and you update that prop in children or that prop update in the parent component so both will re-render.
If you don't want a component to re-render when its parent renders, wrap it with memo. After that, the component indeed will only re-render when its props change.
Now, we know that React components re-render themselves and all their children when the state is updated. In this case, on every mouse move the state of MovingComponent is updated, its re-render is triggered, and as a result, ChildComponent will re-render as well.
But, if we use the useMemo() Hook, we can avoid component re-rendering if the inputs are the same and save the result in the cache. Now, the computed result is stored in the cachedValue variable and useMemo() Hook will return it each time unless the inputs are changed.
When you want to update a child without updating the parent, the state must be in the child. You can pass the state getter / setter from the child to the parent to be able to read and update it:
function Child({onMount}) {
const [value, setValue] = useState(0);
useEffect(() => {
onMount([value, setValue]);
}, [onMount, value]);
return (
<div>
{value}
</div>
);
};
function Parent() {
let value = null;
let setValue = null;
const onChildMount = (dataFromChild) => {
value = dataFromChild[0];
setValue = dataFromChild[1];
};
// Call setValue to update child without updating parent
return (
<div>
<Child onMount={onChildMount}/>
</div>
);
};
Since const [value, setValue] = useState(0);
is in the Child
, only the child component will re render when updating the value. Additionally, since the Parent
receives value
and setValue
at onChildMount
, the parent can use them to update the child without re rendering the parent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With