React Hooks之useState

345 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

useState

useState为函数组件提供状态(state),在class组件中需要在constructor中初始化数据,并使用this.setState更新数据。

使用方法

 const [state, setState] = useState(initialState);

这里需要更新state数据需要调用setState方法,有两种写法

 //1、直接调用setState传入更新的数据
 setState(state + 1)
 ​
 //2、对于复杂的更新逻辑使用函数式代替
 setState(() => state + 1)

如果定义的初始数据是引用类型,使用扩展运算符

 const [state, setState] = useState({});
 ​
 setState(() => {
     return {
         ...state,
         //更新属性
     }
 })

实例

 import React, { useState } from 'react';
 ​
 function Example() {
   // 声明一个叫 "count" 的 state 变量
   const [count, setCount] = useState(0);
 ​
   return (
     <div>
       <p>You clicked {count} times</p>
       <button onClick={() => setCount(count + 1)}>
         Click me
       </button>
     </div>
   );
 }

更新引用类型

 import React, { useState } from 'react';
 ​
 export default function Example() {
   const [person, setPerson] = useState({
       name: 'Ynacy',
       age: 21
   });
 ​
   function changeUserInfo(){
       setPerson(()=>{
           return {
               ...person,
               age: person.age + 1
           }
       })
   }
   return (
     <div>
       <p>Name: {person.name}</p>
       <p>Age: {person.age}</p>
       <button onClick={changeUserInfo}>
         Click me
       </button>
     </div>
   );
 }

useStae惰性初始化

1、惰性state

initalState参数只会在组件的初始渲染中起作用,后序渲染时会被忽略(不然每次都会赋初始值,完全没必要)

2、复杂初始state的定义

初始state需要通过复杂计算获得,则可以传入一个函数,在函数中计算并返回初始化的state

3、如果state的值没有改变,那么组件不会更新

 import React, { useState } from 'react';
 ​
 export default function Example() {
   // 声明一个叫 "count" 的 state 变量
   const [count, setCount] = useState(0);
 ​
   console.log('组件更新了!');
 ​
   return (
     <div>
       <p>You clicked {count} times</p>
       {/* setCount(count)不会修改count的值 */}
       <button onClick={() => setCount(count)}>
         Click me
       </button>
     </div>
   );
 }

此时发现,点击按钮并不会触发组件的更新。

Strict Mode

dev模式下render使用的是strict mode,strict mode的通过两次调用constructor和render函数来更好的检测不符合预期的side effects。

这也是我在上个例子中发现,更新state,会触发两次组件的更新

 import React, { useState } from 'react';
 ​
 export default function Example() {
   // 声明一个叫 "count" 的 state 变量
   const [count, setCount] = useState(0);
 ​
   console.log('组件更新了!');
 ​
   return (
     <div>
       <p>You clicked {count} times</p>
       {/* setCount(count)不会修改count的值 */}
       <button onClick={() => setCount(count + 1)}>
         Click me
       </button>
     </div>
   );
 }

严格模式不能自动检测到你的副作用,但它可以帮助你发现它们,使它们更具确定性。通过故意重复调用以下函数来实现的该操作:

  • class 组件的 constructorrender 以及 shouldComponentUpdate 方法
  • class 组件的生命周期方法 getDerivedStateFromProps
  • 函数组件体
  • 状态更新函数 (即 setState 的第一个参数)
  • 函数组件通过使用 useStateuseMemo 或者 useReducer

严格模式 – React (reactjs.org)