When updating a stateful component in React is it considered a bad practice when a component uses the current state to update the new state.
For example if I have a class that stores whether a filter is open or not in it's state, is one of these options for updating the state more desirable than the other in terms of performance?
Option 1:
class Container extends Component {
state = {
show: false
}
show = () => this.setState({ show: true })
hide = () => this.setState({ show: false })
render() {
<ExternalComponent
show={this.show}
hide={this.hide}
/>
}
}
Option 2:
class Container extends Component {
state = {
show: false
}
toggleVisibility = () => this.setState({ show: !this.state.show })
render() {
<ExternalComponent
toggleVisibility={this.toggleVisibility}
/>
}
}
Option 3:
class Container extends Component {
state = {
show: false
}
setShow = (newVal) => this.setState({ show: newVal })
render() {
<ExternalComponent
setShow={this.setShow}
/>
}
}
The setState () method enqueues all of the updates made to the component state and instructs React to re-render the component and its children with the updated state. Always use the setState () method to change the state object, since it will ensure that the component knows it’s been updated and calls the render () method.
Whenever the state changes, React re-renders the component to the browser. Before updating the value of the state, we need to build an initial state setup. Once we are done with it, we use the setState () method to change the state object. It ensures that the component has been updated and calls for re-rendering of the component.
It ensures that the component has been updated and calls for re-rendering of the component. Syntax: We can use setState() to change the state of the component directly as well as through an arrow function. setState({ stateName : updatedStateValue }) // OR setState((prevState) => ({ stateName: prevState.stateName + 1 }))
This article will help you get familiar with a very important concept of React, the state. React State holds the data for a component. The component, in turn, returns the data contained within the state to the output. What Is ‘State’ in ReactJS?
There is nothing wrong with a component accessing its own state. Write-only state wouldn't be terribly useful! However, you should be very careful when exposing component state or state-altering methods to other components. Component state is internal, and should only been touched from outside via a well-considered interface, to prevent your components from becoming an entangled mess.
In fact, there is an example that is similar to your Example #2 in the React documentation:
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
Note a difference from your example, however. The toggle method needs to be bound in the constructor, to ensure that this
means what you're expecting it to mean.
If the wrapping component is the one keeping track of the visibility of the child ExternalComponent
, then rather than passing the toggle method into the child component, I would expect the wrapper to render a hide/show affordance of some sort, and then either pass the current visibility into the child component as a prop or selectively render it (note that selective rendering will cause the entire child component to be remounted when it's enabled again, which may be expensive; you may be better off hiding it than tearing it down and recreating it). That makes the division of concerns clear: the wrapper knows about visibility, and the child component doesn't need to know how or why that decision was made, nor does it need to touch the wrapper's internal state.
There is nothing wrong with using the current state's value to determine the new state value.
Option 2 has less code, which kind of appeals to me. However, sometimes I might have to use Option 1 when using a third-party component (e.g. Semantic UI React modal) and it has show and hide handlers that we have to define.
Option 3 is also fine; I would use it for other applications other than this show/hide one (in fact, that one is used pretty much all the time, especially when you have controlled input components).
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