State
In React, state is a built-in object that allows components to create and manage their own data. Unlike props
, which are passed down from a parent component, state is local and encapsulated within the component itself. State is what allows React components to be dynamic and interactive.
How to Initialize State
State is usually initialized in the constructor of a class-based component:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
}
In functional components, you can use the useState
hook to initialize state:
import React, { useState } from 'react';
const MyComponent = () => {
const [count, setCount] = useState(0);
/**
* 1. the value would be stored in `count`
* 2. The Value of count would be updated by method `setCount`
* 3. The userState tells the React that when count value udpated re render the component
* 4. The 0 value in useSate() method represents the intial value of count.
*/
};
Updating State
State should never be modified directly. Instead, use setState
in class-based components:
this.setState({ count: this.state.count + 1 });
Or the state updater function in functional components:
setCount(count + 1);
Using State
You can access the state object directly within the render
method of a class-based component:
render() {
return <div>{this.state.count}</div>;
}
Or directly within the functional component:
return <div>{count}</div>;
Why State is Important
Reactivity: State allows React to re-render the component when data changes, making the UI dynamic.
Encapsulation: Each component manages its own state, making it easier to debug and reason about your application.
Data Flow: State allows for a "single source of truth," where data flows in a unidirectional manner, making it easier to manage.
Best Practices
Minimize Statefulness: Only use state in components where it's necessary. Stateless components are easier to test and maintain.
Initialize Correctly: Always initialize state with the data type you expect to use. If it's an array, initialize it as an empty array, not
null
orundefined
.Functional Updates: When the new state depends on the old state, use functional updates to ensure accuracy.
this.setState((prevState) => ({ count: prevState.count + 1 }));
Batch Updates: React batches multiple
setState
calls for performance optimization. Be aware that consecutivesetState
calls might not reflect immediately.Use Component Lifecycle / Effects: In class-based components, use lifecycle methods like
componentDidMount
andcomponentDidUpdate
to handle side-effects related to state. In functional components, use theuseEffect
hook.
By understanding and effectively using state in React, you can build more robust and interactive UIs.
Arrays or objects as steate variable
When you change something in the state, React checks if the new value is different from the old one. If it is, React updates the state and re renders the component. This helps make the app faster. This works well for simple data types like numbers and strings. But for more complex data types like arrays or objects, it will not work as expected. Let's look at an example to understand this better.
In this case, the variable 'a' is a number. In JavaScript, number variables store their own values. So, even when we change value of variable 'temp', it won't affect 'a'. Once temp is created it will not have any relation with variable 'a'. Now, let's see what happens when we use complex data types like arry or objects instead.
Due to the fact that objects are stored by reference, both variables 'a' and 'temp' will always point to the same object. So, even if the value of 'temp' changes later in the code above, both 'a' and 'temp' will still represent the exact same object.
Also, it's important to understand that the comparison of complex objects doesn't just compare values. For this reason, even when complex data types represent the same values, comparing them would yield a false response.
Now, let's examine how using setState on objects or arrays will affect the component if we follow similar steps to change the value in the state.
Once you click on the Add
button, the function updateColorsList
will add the value from the input to the colors
array. Then the code will set the state using setColors
function.
Before updating the state, The React will try to compare the previous and current colors
state values. The React will identify that both are the same and won't re-render the component.
Using complex objects right way
It's quite simple to solve this problem. As we've learned, objects or arrays in JavaScript are stored by reference value. We should always create a new instance of the existing variable by cloning it. Depending on the data type, there are various ways to clone a variable in JavaScript. The simplest method that works for both arrays and objects is using the destructuring technique.
It is not necessary to use temp variable, in general practice it would be written as setColors([... colors, colorInput]);