Using setState() method in React
React is built on the foundation of truly reusable and encapsulated components, that are also meant to be self-managing. This means that the data update mechanism should be an internal detail of every component.
Have a look at the given React app:
- The
greetingsfunction:- Line 5: Takes in an object
target. - Line 6: Extracts
valuefrom it. - Line 12, 16-19: Renders a greeting message.
- Line 5: Takes in an object
- On each change in the
inputelement, thegreetingmethod is called again to render an updated greeting (Line 10).
import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css';
function greetings({ target }) {
var value = target? target.value : "";
const element = (
<div className="text-center my-2">
<label> Full Name: </label>
<input type="text" name="fullname" onChange={greetings} />
<div className="border border-primary py-3">
<h4> Greetings, {value}!</h4>
</div>
</div>
);
ReactDOM.render(
element,
document.getElementById('root')
);
}
greetings({});This works perfectly fine. But what if another component needs to read the current value of the greeting component? That is achievable if we declare greeting to be a class, rather than a function, so that its objects may also store variables accessible across components.
Adding state to components
Have a look at the updated React app given below:
- Line 4: Convert the greeting method to a class.
- Line 5-7: Maintain a local state with useful variables.
- Line 11-13: Every time the
stateChangemethod is invoked, it extractsvaluefrom the passed target argument, and uses thesetState()method to update the local values.
Warnings:
1. You should never update the state directly (i.e.this.state.var = updatedVar).
2. React may batch run multiplesetState()calls for performance. So you should never rely on the directly modified values to calculate the next state, without the use of a callback function.
import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.css';
class Greeting extends Component {
state = {
fullname: '',
}
stateChange = (f) => {
const {name, value} = f.target;
this.setState({
[name]: value,
});
}
render() {
return (
<div className="text-center">
<label htmlFor="fullname"> Full Name: </label>
<input type="text" name="fullname" onChange={this.stateChange} />
<div className="border border-primary py-3">
<h4> Greetings, {this.state.fullname}!</h4>
</div>
</div>
);
}
}
export default Greeting;Free Resources