Close
    Close full mode
    logoYonisfy

    State Management (hooks)

    Git RepositoryContribute on Github
    Last update: 6 months ago by mohammedelzanatyReading time: 6 min

    State Management

    In React, state refers to a structure that keeps track of how data changes over time in your application.

    The state is an instance of React Component Class can be defined as an object of a set of observable properties that control the behavior of the component. In other words, the State of a component is an object that holds some information that may change over the lifetime of the component.

    State Types

    Let's know first What are the types of State in React

    I think it will be a better idea after knowing the types of state is to know how to manage it. I will make a simple counter app and build it with different state management logic here's the starter code sandbox πŸ’» to be able to play with it

    Class-Based State

    I need from you to think of the state as plain object which contain the some data. when a state property is updated, React re-renders the component accordingly.

    In class components, there are two ways to initialize state:-

    1. Constructor function

      • it's regular functions introduced in ES6, but there’s a common agreement to name them with capital letter first
      • it's the first function called in a class when it is first instantiated
      • when a new object is created from the class. Initializing the state within the constructor function allows the state object to be created before React renders the component.
      class ClassComponent extends Component {
      constructor(props) {
      super(props);
      this.state = {
      count: 0,
      };
      }
      // ...
      }
    2. Class property

      • This enables defining class properties for your JavaScript classes. This can be particularly useful for React components. It combats messy things like binding event handlers in the constructor 🀒 u can read more about it from here

    Both approaches net the same output so it all just comes down to preference. I’ll be sticking with the constructor function approach in our example. simply I need to create a simple counter with the ability to increment, decrement and reset. we will start basically by defining the state object with simple count property in the constructor function

    //...
    class App extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    count: 0,
    };
    }
    //...
    }

    the above snippet maily tell react that we have property cause re-rendering every time it changes. so the question now is how we can change it what's the trigger.. as you say we need to define click handler to change. Don't worry i will do this for you and attached it to the buttons

    //..
    class App extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    count: 0
    };
    }
    + increment() {
    + this.setState({ count: this.state.count + 1 })
    + }
    + decrement () {
    + this.setState({ count: this.state.count - 1 });
    + };
    + reset() {
    + this.setState({ count: 0 });
    + }
    render() {
    + const { count } = this.state;
    return (
    <div className="App">
    <header className="App-header">State Management Starter Code</header>
    <main>
    + <p className="count">{count}</p>
    <div className="controls">
    + <button className="primary" onClick={this.increment}>Increment</button>
    + <button className="danger" onClick={this.decrement}>Decrement</button>
    + <button className="info" onClick={this.reset}>Reset</button>
    </div>
    </main>
    </div>
    );
    }
    }
    export default App;

    now every thing is good and sounds fine but if you try to press any button nothing will happen and you will get errors in the console and there's a reason for this, as you say it's this this is the problem. if you not familar with this in javascript I make a video about it watch it now πŸ˜‰ ... I am waiting you here don't worry

    so now we need to overcome of the problem of binding a function to a component instance and this can be done by four different ways

    //..
    class App extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    count: 0
    };
    + // 1. Bind in Constructor (ES2015)
    + this.reset = this.reset.bind(this);
    }
    increment() {
    this.setState({ count: this.state.count + 1 })
    }
    + // 2. Class Properties (Stage 3 Proposal)
    + decrement = () => {
    this.setState({ count: this.state.count - 1 });
    };
    reset() {
    this.setState({ count: 0 });
    }
    render() {
    const { count } = this.state;
    return (
    <div className="App">
    <header className="App-header">State Management Starter Code</header>
    <main>
    <p className="count">{count}</p>
    <div className="controls">
    + {/* 3. Bind in Render */}
    + <button className="primary" onClick={this.increment.bind(this)}>Increment</button>
    <button className="danger" onClick={this.decrement}>Decrement</button>
    <button className="info" onClick={this.reset}>Reset</button>
    + {/* 4. Arrow Function in Render */}
    + {/*<button className="primary" onClick={() => this.increment()}>Increment</button>*/}
    </div>
    </main>
    </div>
    );
    }
    }
    export default App;

    I see now it's working and you are happy, u can read more but there's also something I need from you to pay attention to which is asynchronicity of setState function for example:-

    //...
    increment() {
    this.setState({ count: this.state.count + 1 });
    this.setState({ count: this.state.count + 1 });
    this.setState({ count: this.state.count + 1 });
    this.setState({ count: this.state.count + 1 });
    }
    //...

    in the above example the count -> 1 because react will queuing up state changes, and will batch them up then efficiently make that changes so underneath it will be something like

    Object.assign(
    {},
    yourFirstCallToSetState,
    yourSecondCallToSetState,
    yourThirdCallToSetState,
    yourFourthCallToSetState
    );

    which result merge them all and the last one win

    one more thing we need to pay attention to that traditionally we pass an object to setState but we can pass other things like function and that function has some arguments the first one will be state and return an object with the new state, one more important think I need to hight here if we do the same multiple setState but with function version the result will be different

    //...
    increment() {
    this.setState(prevState => { return { count: prevState.count + 1 } });
    this.setState(prevState => { return { count: prevState.count + 1 } });
    this.setState(prevState => { return { count: prevState.count + 1 } });
    this.setState(prevState => { return { count: prevState.count + 1 } });
    }
    //...

    in the above example the count -> 4 because in this case react will not merge them like objects I know you can compose it but it's not the case don't be cleaver πŸ˜„ but function will give us the ability to add condition for example like

    //...
    increment() {
    let max = 5;
    this.setState((prevState) => {
    if (prevState.count >= max) return;
    return { count: prevState.count + 1 };
    });
    //...

    that's cool ha, but there's a situations u might need to do something after the state is updated. fortunately the react provide a solution for this situation by passing a callback function as second argument for setState method

    //...
    increment() {
    let max = 5;
    this.setState(
    (prevState) => {
    if (prevState.count >= max) return;
    return { count: prevState.count + 1 };
    },
    () => {
    console.log("After!", this.state); // Count - 1
    }
    );
    console.log("Before!", this.state); // Count - 0
    }
    //...
    ❓ Now after you understand how the use setState it's time to do some work
    I need to update the title of the document everytime the state changes. even in increment, decrement or reset
    // hint: use document.title

    πŸ’» πŸ”₯ 🧨 This sandbox represents where are we

    Hooks State

    There is nothing so far πŸ‘¨πŸ»β€πŸ’» Coming Soon 🀌🏻 πŸ€·πŸ»β€β™‚οΈ

    Reducers

    There is nothing so far πŸ‘¨πŸ»β€πŸ’» Coming Soon 🀌🏻 πŸ€·πŸ»β€β™‚οΈ

    Context

    There is nothing so far πŸ‘¨πŸ»β€πŸ’» Coming Soon 🀌🏻 πŸ€·πŸ»β€β™‚οΈ

    Data Fetching

    There is nothing so far πŸ‘¨πŸ»β€πŸ’» Coming Soon 🀌🏻 πŸ€·πŸ»β€β™‚οΈ

    Thunks

    There is nothing so far πŸ‘¨πŸ»β€πŸ’» Coming Soon 🀌🏻 πŸ€·πŸ»β€β™‚οΈ

    πŸ› οΈ Technologies β€” Previous
    React Router
    Next β€” πŸ› οΈ Technologies
    Protected Route