Welcome to Aaron Blog! en and jp version is now updating! 🎉

Day 3 State and Side Effects

Learning the React Framework

Loading comments...

Learning the React Framework - 003 Component State and Side Effect Updates

State Abstraction

In actual development scenarios, frontend receives a lot of data, whether it's initial default data for the page or API data passed from the backend. We need a method to save this data, and state is a function implemented by React.

According to the description in React's basic concept theory, UI is influenced by State to change into different forms. We hope each UI can preserve its own state and unidirectionally update state through functions we design.

From Basic Concepts
/* Combining state management with UI logic abstraction, just like components, we define parameters coming in through props,
  and update the passed down state according to side effect functions.
  Notice that the abstract component doesn't have other functions that trigger side effects,
  this is to maintain data state immutability - data can only change unidirectionally according to our design.
*/
function FancyNameBox(user, likes, onClick) {
  return FancyBox([
    'Name: ',
    NameBox(`${user.firstName} ${user.lastName}`),
    'Likes: ',
    LikeBox(likes),
    LikeButton(onClick),
  ]);
}

// Implementation Details (Set initial state value and side effect function to update state)

let likes = 0;
function addOneMoreLike() {
  likes++;
  rerender(); // Very important - when state updates, we need to trigger page update
}

// Init - Data state initialization

FancyNameBox(
  { firstName: 'Sebastian', lastName: 'Markbåge' },
  likes,
  addOneMoreLike
);

useState

Components in React are just function encapsulations. When a function is executed, its memory reference gets cleared. We want state to persist in our components according to page logic usage. React implemented a hook (which can be viewed as an official utility function) called useState that allows state to persist.

Example

How useState Works Internally

Simply put, useState does two things for us:

  1. Allows state values that would otherwise not persist after rerender to continue existing.
  2. Triggers rerender again after state updates.
// Simple abstraction
function useState(state) {
  const setState = (action) => {
    action(state);
    React.root.reRender(<App />); // rerender
  };
  return [state, setState];
}

Each time we call useState, we receive the state and the side effect function that triggers it from the function, then update the page. This abstraction is just a very simple description. The actual implementation is much more complex, involving initial value observation, node slicing, etc... Really quite interesting 😇😇

State Management for Arrays and Objects

When managing object data with state, we can use destructuring to modify state, Example

For array data state management, just like objects, we shouldn't directly change values in the array, but need to create or return new objects.

setAry(
  // Replace the state
  [
    // with a new array
    ...ary,
    { id: nextId++, name },
  ]
);

Additionally, when changing complex object types, be careful about whether you're changing shared memory references, otherwise unexpected errors can easily occur.

Resetting State with Key

Key is an attribute that identifies nodes, commonly used when rendering lists, allowing React to identify the uniqueness of nodes. But when managing state, you can also use Key to reset state. This mainly utilizes the characteristic that when key values change, rerendering occurs.

Example

References

If you want to understand why state is immutable, you can go here

Loading comments...