State attributes in React components

The state of the functional component, that is, the stateless component


Use useState() for state management


  • useState()Hook to enable state in function components
  • useState(initialValue)The first parameter initialValueis the initial value of the state
  • [state, setState] = useState(initialValue)Return an array containing 2 elements: state value and state update function
  • Call the status updater function to setState(newState)update the status with the new value . Alternatively, you can use a callback setState(prev => next)to invoke state updater, the callback will return to a new state based on the previous state
  • After calling the state updater, React makes sure to re-render the component so that the new state becomes the current state
Example description
import React, {
    
    useState, useEffect} from 'react';
import './App.css';

function App(props) {
    
    

    // 函数组件,即无状态组件,也可以使用状态
    /*
    * useState() 函数接受一个参数:initialState 初始状态,
    *   返回一个数组,数组内有 2 个元素,可以解构
    *       第 1 个元素:initialState,即 useState 函数传的值
    *       第 2 个元素:是 1 个函数,可以修改 initialState 值
    *           第 2 个元素函数,可以接收 3 个参数
    *           第 1 个参数:更新的内容
    *
    * */

    const [count, setCount] = useState(0);

    return (
        <div className="App">

            <p>你点击了 {
    
    count}</p>
            <button onClick={
    
    () => setCount(count + 1)}>点击</button>
        </div>
    );
}

export default App;
useState-initialState initial state

The initial value can accept any parameters, but remember that when it is accepted as a function, it becomes Lazy initialization. The return value of the function is initialState

const [count, setCount] = useState(0);

const [count, setCount] = useState(()=>0);
// 这两种初始化方式 是相等的,但是在函数为初始值时会被执行一次

const [count, setCount] = useState(()=>{
    
    
    console.log('这里只会在初始化的时候执行')
    // class 中的 constructor 的操作都可以移植到这里
    return 0
});
// 当第一次执行完毕后 就和另一句的代码是相同的效果了

Note:
useState-setState
may often use its callback function when using the setState of the class,
but it is a pity that he only accepts new values. If you want the corresponding callback, you can use useEffect. This question will wait Will provide a redirect link

Multiple states


  • By calling useState() multiple times, a functional component can have multiple states
function MyComponent() {
    
    
  const [state1, setState1] = useState(initial1);
  const [state2, setState2] = useState(initial2);
  const [state3, setState3] = useState(initial3);
  // ...
}

It should be noted that to ensure that multiple calls to useState() always maintain the same order between renderings (described later).

We add a button to add a bulb, and add a new state to save the number of bulbs, when the button is clicked, a new bulb will be added.

The new state count contains the number of bulbs, and the initial value is 1:

import React, {
    
     useState } from 'react';

function Bulbs() {
    
    
  const [on, setOn] = useState(false);
  const [count, setCount] = useState(1);

  const lightSwitch = () => setOn(on => !on);
  const addBulbs = () => setCount(count => count + 1);

  const bulb = <div className={
    
    on ? 'bulb-on' : 'bulb-off'} />;
  const bulbs = Array(count).fill(bulb);

  return (
    <>
      <div className="bulbs">{
    
    bulbs}</div>
      <button onClick={
    
    lightSwitch}>/</button>
      <button onClick={
    
    addBulbs}>添加灯泡</button>
    </>
  );
}

Switch light diagram

  • [on, setOn] = useState(false) Manage on/off state
  • [count, setCount] = useState(1) manages the number of bulbs.

Multiple states can work correctly in one component.

Delayed initialization of state


Whenever React re-renders the component, useState(initialState) is executed. If the initial state is the original value (number, boolean, etc.), there will be no performance issues.

When the initial state requires expensive performance operations, you can use the delayed initialization of the state by providing a function for useState(computeInitialState), as shown below:

function MyComponent({
    
     bigJsonData }) {
    
    
  const [value, setValue] = useState(function getInitialState() {
    
    
    const object = JSON.parse(bigJsonData); // expensive operation
    return object.initialValue;
  });

  // ...
}

getInitialState() is executed only once during the initial rendering to obtain the initial state. In future component rendering, getInitialState() will not be called again, thus skipping expensive operations.

To make the function component stateful, call useState() in the function body of the component.

The first parameter of useState(initialState) is the initial state. The returned array has two items: current state and state update function.

const [state, setState] = useState(initialState); Use
setState(newState) to update the state value.
In addition, if you need to update the state based on the previous state, you can use the callback function setState(prevState => newState).

There can be multiple states in a single component: call useState() multiple times.

Lazy initialization is convenient when the initial state overhead is large. Use the callback to calculate the initial state to call useState(computeInitialState), and this callback is executed only once during the initial rendering.

You must ensure that useState() follows the Hook rules.

When the closure captures obsolete state variables, the problem of obsolete state arises. This problem can be solved by using a callback to update the state, which will calculate the new state based on the previous state.

Finally, you will use useState() to manage a simple state. To handle more complex states, a better option is to use the useReducer() hook.

useEffect


  • The life cycle can be simulated in the component defined by function
  • Parameter 1: Represents the callback function
  • Parameter 2: Indicates what data change will trigger the callback function;
  • If there is no parameter 2, it means that all data changes will trigger
  • Parameter two is an empty array, which means it will only be triggered when the component is initialized for the first time
  • If the array in parameter 2 has a value, it means that the data in the array will be triggered after a change
Example description
useEffect(() => {
    
    
  console.log('在 dep 改变时触发,若无 dep 则,每次更新组件都会触发')
  return () => {
    
    
    console.log('在组件 unmount 时触发')
  };
});

deps must be an array, but if it is an empty array:

  useEffect(() => {
    
    
    console.log('效果的等于 componentDidMount')
  }, [])

Even if there is deps, it will trigger once during initialization

State of class component


  • state state: store data The
    this.state property is set in the constructor, which is an object that can store data, for example: this.state = {num: 0 };

  • setState Set state: modify data
    setState is a function that needs to be called. It can manipulate the properties in the constructor this.state object, and follow the new view, and trigger the render function

    Call the setState method, and receive 2 parameters through this.setState() and setState methods

The first parameter: the object or callback function is an object: the property name in the object is the property name in the constructor this.state object.
By modifying the property value, you can modify the property value in the this.state object, update the view and trigger the render () Function, for example: this.setState({ num: this.state.num + 1 }) is a callback function: callback function, receiving 2 parameters. The first parameter: state object (stored data). The second parameter : Props property object (the value passed by the parent class through the property exists in the props object) An object returned in the callback function , the object property name is state The property name that needs to be modified, for example: return {n: prevState.n + 1}


The second parameter: is a callback function, which is triggered after the data update is completed, for example: this.setState({ num: this.state.num + 1 },()=>{console.log('Data update completed Trigger the function after');})

Note:
Changing the value of state cannot be changed directly. Changing the view directly will not be synchronized. To change the state, use setState to change.
If this.setState() function is executed multiple times, the last one will be executed. this.setState()
this.setState() is asynchronous Function, first execute the synchronization code and then execute, this.setState(), so to get the value after setState is executed, you need to get the second parameter in the callback function
. The event function does not have this, and you need to bind render through bind In this, and can pass the value through bind

setState() The first parameter is the object


  • state state: store data The
    this.state property is set in the constructor, which is an object that can store data, for example: this.state = {num: 0 };
  • setState set state: modify data
    setState is a function that needs to be called. It can manipulate the properties in the constructor this.state object and follow the new view, and it will trigger the render function to
    call the setState method, which is received by the this.setState(), setState method 2 parameters

The first parameter: the object or callback function is an object: the property name in the object is the property name in the constructor this.state object.
By modifying the property value, you can modify the property value in the this.state object, update the view and trigger the render () function, for example: this.setState({ num: this.state.num + 1 }) The second parameter: is a callback function, which is triggered after the data is updated, for example: this.setState({ num: this.state.num + 1 },()=>{console.log('The function is triggered after the data is updated');})


Example description

  • Set this.state{num:1} in the constructor
  • After the component is mounted, change the value in state this.setState({ num: this.state.num + 1 })
  • Rendering effect is 2
<div id="app"></div>

<script type="text/babel">

    class App extends React.Component {
     
     
        constructor(props) {
     
      // 1 先初始化
            super(props);
            
            // super() 传 props 与 this.props=props; 等价的
            // 父组件也是做的这个事 this.props=props;
            // 执行 super() 只是继承了父组件的实例化属性和方法
            // this.props=props;
            
            // state 存储数据
            this.state = {
     
     
                num: 1
            }
        }

        componentDidMount() {
     
      // 3 渲染完成触发
            // 改值后自动触发 render
            this.setState({
     
      // 连续执行多次 this.setState() 函数会执行最后一个 this.setState()
                num: this.state.num + 1
            }, () => {
     
     
                console.log('数据更新完成后触发')
            })
        }

        render() {
     
      // 2 渲染
            return (
                <div>
                    {
     
     this.state.num}{
     
     /* 渲染 2 */}
                </div>
            )
        }
    }

    ReactDOM.render(<App/>, document.querySelector('#app'));
</script>

Guess you like

Origin blog.csdn.net/weixin_45757442/article/details/104645731