如何通过React hooks实现同步获取多个state值的方法?

2026-03-31 17:531阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1788个文字,预计阅读时间需要8分钟。

如何通过React hooks实现同步获取多个state值的方法?

目录 + React (含 Hooks) 同步获取 state 值 + 环境 + 代码示例 + 异步写入同步方法 + React Hooks 常用方法 + 1.useState + 2.useEffect + 3.useContext 上下文传递值 + 4.useReducer + 5.useMemo + 6.useRef + React (含 Hooks) 同步获取 state 值 + 环境

目录
  • react(含hooks)同步获取state值
    • 环境
    • 代码示例
    • 异步写成同步的方法
  • react hooks常用方法
    • 1.useState
    • 2.useEffect
    • 3.useContext上下文传值
    • 4.useReducer
    • 5.useMemo
    • 6.useRef

react(含hooks)同步获取state值

环境

"dependencies": {     "babel-plugin-transform-decorators-legacy": "^1.3.5",     "customize-cra": "^1.0.0",     "rc-form": "^2.4.11",     "react": "^17.0.1",     "react-app-rewired": "^2.1.8",     "react-dom": "^17.0.1",     "react-router-dom": "^5.2.0",     "react-scripts": "^4.0.1",     "redux": "^4.0.5"   },

代码示例

hooks

如何通过React hooks实现同步获取多个state值的方法?

import {useState} from "react"; export default function Pre04SetStateSync() {     const [counter, setCounter] = useState(0)     const add = () => {         setCounter(counter + 1)         console.log({counter})     }     return <>         <h3>同步SetState</h3>         <p>请观察控制台</p>         <button onClick={add}>counter: {counter}</button>     </> }

class

export default class Pre04SetStateSync extends React.Component{     state = {         counter:0     }     add = () => {         this.setState({counter:this.state.counter + 1})         console.log('~~this.state.counter',this.state.counter)     }     render() {         return <>             <h3>同步SetState</h3>             <p>请观察控制台</p>             <button onClick={this.add}>counter: {this.state.counter}</button>         </>     } }

hooks结构中的setCounter(xxx)相当于class组件写法中setState({counter: xxx})

可以对比控制台看到,这样直接setCounter(setState)后立即输出的counter的是上一次的值,而按钮上显示正确,说明本次更新是异步的(react这样设计是为了批量更新而提高性能),打印时counter还没来得及改变。如果需要set完后立即取到counter的最新值,可以按如下方法实现同步的效果。

异步写成同步的方法

1. 写在setTimeout中

注意,只适用于class组件

add = () => {     setTimeout(()=>{         this.setState({counter:this.state.counter + 1})         console.log('~~this.state.counter',this.state.counter)     },0) }

2. 合成事件使用原生事件替代

注意,只适用于class组件

// 原生事件 export default class Pre04SetStateSync extends React.Component {     state = {         counter: 0     }     componentDidMount() {         document.querySelector('#btn').addEventListener('click', this.add)     }     add = () => {         this.setState({counter: this.state.counter + 1})         console.log('~~this.state.counter', this.state.counter)     }     render() {         return <>             <h3>同步SetState</h3>             <p>请观察控制台</p>             <button id='btn'>counter: {this.state.counter}</button>         </>     } }

3. 写入setState的回调函数中

注意,只适用于class组件

export default class Pre04SetStateSync extends React.Component {     state = {         counter: 0     }     add = () => {         this.setState({counter: this.state.counter + 1}, ()=>{             console.log('~~this.state.counter', this.state.counter)         })     }     render() {         return <>             <h3>同步SetState</h3>             <p>请观察控制台</p>             <button onClick={this.add}>counter: {this.state.counter}</button>         </>     } }

4. 连续setState的问题

注意,class组件和hooks都可以

如果将add改为先加1再加2,会发现代码只执行了最后一个加2,加1被忽略了,如:

const add = () => {     setCounter(counter + 1)     setCounter(counter + 2) }

解决方法是将setState的参数写成函数形式

const add = () => {     setCounter(counter => counter + 1)     setCounter(counter => counter + 2) }

5. 使用副作用useEffect

注意,只适用于hooks

export default function Pre04SetStateSync() {     const [counter, setCounter] = useState(0)     const add = () => {         setCounter(counter + 1)     }     useEffect(() => {         console.log({counter})     }, [counter])          return <>         <h3>同步SetState</h3>         <p>请观察控制台</p>         <button onClick={add}>counter: {counter}</button>     </> }

react hooks常用方法

1.useState

function Example01(){     const [ count, setCount ] = useState(0)  //声明     return(         <div>             <p>{count}</p>  //读取             <button onClick={()=>setCount(count+1)}>计数</button> // 使用(修改)         </div>     ) }

2.useEffect

1.React首次渲染和之后的每次渲染都会调用一遍useEffect函数,而之前我们要用两个生命周期函数分别表示首次渲染(componentDidMonut)和更新导致的重新渲染(componentDidUpdate)

2.useEffect中定义的函数的执行不会阻碍浏览器更新视图,也就是说这些函数时异步执行的,而componentDidMonut和componentDidUpdate中的代码都是同步执行的。

注意:

如果useEffect后面没有依赖:

这种时候每次每次页面更新都会执行

useEffect(()=>{     console.log('执行'); })

如果后面为空

页面初始的时候执行一次

useEffect(()=>{     console.log('执行'); },[])

如果后面有值且不为空

只有当count改变时才会被触发

useEffect(()=>{     console.log('执行'); },[count])

使用useEffect解绑,组件卸载的时候,比如需要清除计时器等:

但是当传空数组[]时,就是当组件将被销毁时才进行解绑,这也就实现了componentWillUnmount的生命周期函数。

function Index() {     useEffect(()=>{         console.log('useEffect=>Index')         return ()=>{             console.log('Index页面离开')         }     },[])     return <h2>测试解绑</h2>; }

3.useContext上下文传值

1.父组件:

const CountContext = createContext()  //引入 function Example01(){     const [ count, setCount ] = useState(0)     return(         <div>             <p>{count}</p>             <button onClick={()=>setCount(count+1)}>计数</button>             <CountContext.Provider value={count}>  //使用包裹子组件传递值                 <ChildContent/>             </CountContext.Provider>               </div>     ) }

2.子组件:

function ChildContent(){      const context = useContext(CountContext)       return(          <p>{context}</p>      ) }

4.useReducer

它也是React hooks提供的函数,可以增强我们的Reducer,实现类似Redux的功能。

import React, { useReducer  } from 'react' function Example5(){     const [ count, dispatch ] = useReducer((state,action)=>{                 switch(action){   //通过判断对应的action,去执行对应的方法             case 'add':                 return state+1             case 'sub':                 return state-1             default:                 return state         }     },1)     return(         <div>             <p>{count}</p>             <button onClick={()=>dispatch('add')}>add</button>  //通过dispatch,传递对应的action,调用对应的方法             <button onClick={()=>dispatch('sub')}>sub</button>         </div>     ) } export default Example5

5.useMemo

useMemo主要用来解决使用React hooks产生的无用渲染的性能问题。

只要使用useMemo,然后给她传递第二个参数,参数匹配成功,才会执行。

1.在父组件里面,传递对应需要的参数

import React , {useState,useMemo} from 'react'; function Example7(){     const [one , setOne] = useState('第一个的状态')     const [two , setTwo] = useState('志玲待客状态')     return (         <>             <button onClick={()=>{setOne(new Date().getTime())}}>第一个</button>             <button onClick={()=>{setTwo(new Date().getTime())}}>第二个</button>             <ChildComponent name={one}>{two}</ChildComponent>         </>     ) }

2.父组件调用子组件

function ChildComponent({name,children}){     function changeXiaohong(name){         return name     }  const actionXiaohong = useMemo(()=>changeXiaohong(name),[name])     return (         <>             <div>{actionXiaohong}</div>             <div>{children}</div>         </>     ) }

6.useRef

用useRef获取React JSX中的DOM元素,获取后你就可以控制DOM的任何东西了。但是一般不建议这样来作,React界面的变化可以通过状态来控制

import React, { useRef } from 'react' function Example8(){     const inputRef  = useRef(null)     const onButtonClick=()=>{         inputRef.current.value='THIS IS INPUT'         console.log(inputRef);     }     return(         <div>             <input type="text" ref={inputRef}/>             <button onClick = {onButtonClick}>显示</button>         </div>     ) } export default Example8

保存普通变量

import React, { useRef,useState } from 'react' function Example8(){     const inputRef  = useRef(null)     const onButtonClick=()=>{         inputRef.current.value='THIS IS INPUT'         console.log(inputRef);     }      const [state, setstate] = useState('inputValue')  //声明一个变量     return(         <div>             <input type="text" ref={inputRef}/>             <button onClick = {onButtonClick}>显示</button>             <input value={state} type="text" onChange={(e)=>setstate(e.target.value)}/>  //绑定对应的值以及绑定onChange事件         </div>     ) } export default Example8

以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。

本文共计1788个文字,预计阅读时间需要8分钟。

如何通过React hooks实现同步获取多个state值的方法?

目录 + React (含 Hooks) 同步获取 state 值 + 环境 + 代码示例 + 异步写入同步方法 + React Hooks 常用方法 + 1.useState + 2.useEffect + 3.useContext 上下文传递值 + 4.useReducer + 5.useMemo + 6.useRef + React (含 Hooks) 同步获取 state 值 + 环境

目录
  • react(含hooks)同步获取state值
    • 环境
    • 代码示例
    • 异步写成同步的方法
  • react hooks常用方法
    • 1.useState
    • 2.useEffect
    • 3.useContext上下文传值
    • 4.useReducer
    • 5.useMemo
    • 6.useRef

react(含hooks)同步获取state值

环境

"dependencies": {     "babel-plugin-transform-decorators-legacy": "^1.3.5",     "customize-cra": "^1.0.0",     "rc-form": "^2.4.11",     "react": "^17.0.1",     "react-app-rewired": "^2.1.8",     "react-dom": "^17.0.1",     "react-router-dom": "^5.2.0",     "react-scripts": "^4.0.1",     "redux": "^4.0.5"   },

代码示例

hooks

如何通过React hooks实现同步获取多个state值的方法?

import {useState} from "react"; export default function Pre04SetStateSync() {     const [counter, setCounter] = useState(0)     const add = () => {         setCounter(counter + 1)         console.log({counter})     }     return <>         <h3>同步SetState</h3>         <p>请观察控制台</p>         <button onClick={add}>counter: {counter}</button>     </> }

class

export default class Pre04SetStateSync extends React.Component{     state = {         counter:0     }     add = () => {         this.setState({counter:this.state.counter + 1})         console.log('~~this.state.counter',this.state.counter)     }     render() {         return <>             <h3>同步SetState</h3>             <p>请观察控制台</p>             <button onClick={this.add}>counter: {this.state.counter}</button>         </>     } }

hooks结构中的setCounter(xxx)相当于class组件写法中setState({counter: xxx})

可以对比控制台看到,这样直接setCounter(setState)后立即输出的counter的是上一次的值,而按钮上显示正确,说明本次更新是异步的(react这样设计是为了批量更新而提高性能),打印时counter还没来得及改变。如果需要set完后立即取到counter的最新值,可以按如下方法实现同步的效果。

异步写成同步的方法

1. 写在setTimeout中

注意,只适用于class组件

add = () => {     setTimeout(()=>{         this.setState({counter:this.state.counter + 1})         console.log('~~this.state.counter',this.state.counter)     },0) }

2. 合成事件使用原生事件替代

注意,只适用于class组件

// 原生事件 export default class Pre04SetStateSync extends React.Component {     state = {         counter: 0     }     componentDidMount() {         document.querySelector('#btn').addEventListener('click', this.add)     }     add = () => {         this.setState({counter: this.state.counter + 1})         console.log('~~this.state.counter', this.state.counter)     }     render() {         return <>             <h3>同步SetState</h3>             <p>请观察控制台</p>             <button id='btn'>counter: {this.state.counter}</button>         </>     } }

3. 写入setState的回调函数中

注意,只适用于class组件

export default class Pre04SetStateSync extends React.Component {     state = {         counter: 0     }     add = () => {         this.setState({counter: this.state.counter + 1}, ()=>{             console.log('~~this.state.counter', this.state.counter)         })     }     render() {         return <>             <h3>同步SetState</h3>             <p>请观察控制台</p>             <button onClick={this.add}>counter: {this.state.counter}</button>         </>     } }

4. 连续setState的问题

注意,class组件和hooks都可以

如果将add改为先加1再加2,会发现代码只执行了最后一个加2,加1被忽略了,如:

const add = () => {     setCounter(counter + 1)     setCounter(counter + 2) }

解决方法是将setState的参数写成函数形式

const add = () => {     setCounter(counter => counter + 1)     setCounter(counter => counter + 2) }

5. 使用副作用useEffect

注意,只适用于hooks

export default function Pre04SetStateSync() {     const [counter, setCounter] = useState(0)     const add = () => {         setCounter(counter + 1)     }     useEffect(() => {         console.log({counter})     }, [counter])          return <>         <h3>同步SetState</h3>         <p>请观察控制台</p>         <button onClick={add}>counter: {counter}</button>     </> }

react hooks常用方法

1.useState

function Example01(){     const [ count, setCount ] = useState(0)  //声明     return(         <div>             <p>{count}</p>  //读取             <button onClick={()=>setCount(count+1)}>计数</button> // 使用(修改)         </div>     ) }

2.useEffect

1.React首次渲染和之后的每次渲染都会调用一遍useEffect函数,而之前我们要用两个生命周期函数分别表示首次渲染(componentDidMonut)和更新导致的重新渲染(componentDidUpdate)

2.useEffect中定义的函数的执行不会阻碍浏览器更新视图,也就是说这些函数时异步执行的,而componentDidMonut和componentDidUpdate中的代码都是同步执行的。

注意:

如果useEffect后面没有依赖:

这种时候每次每次页面更新都会执行

useEffect(()=>{     console.log('执行'); })

如果后面为空

页面初始的时候执行一次

useEffect(()=>{     console.log('执行'); },[])

如果后面有值且不为空

只有当count改变时才会被触发

useEffect(()=>{     console.log('执行'); },[count])

使用useEffect解绑,组件卸载的时候,比如需要清除计时器等:

但是当传空数组[]时,就是当组件将被销毁时才进行解绑,这也就实现了componentWillUnmount的生命周期函数。

function Index() {     useEffect(()=>{         console.log('useEffect=>Index')         return ()=>{             console.log('Index页面离开')         }     },[])     return <h2>测试解绑</h2>; }

3.useContext上下文传值

1.父组件:

const CountContext = createContext()  //引入 function Example01(){     const [ count, setCount ] = useState(0)     return(         <div>             <p>{count}</p>             <button onClick={()=>setCount(count+1)}>计数</button>             <CountContext.Provider value={count}>  //使用包裹子组件传递值                 <ChildContent/>             </CountContext.Provider>               </div>     ) }

2.子组件:

function ChildContent(){      const context = useContext(CountContext)       return(          <p>{context}</p>      ) }

4.useReducer

它也是React hooks提供的函数,可以增强我们的Reducer,实现类似Redux的功能。

import React, { useReducer  } from 'react' function Example5(){     const [ count, dispatch ] = useReducer((state,action)=>{                 switch(action){   //通过判断对应的action,去执行对应的方法             case 'add':                 return state+1             case 'sub':                 return state-1             default:                 return state         }     },1)     return(         <div>             <p>{count}</p>             <button onClick={()=>dispatch('add')}>add</button>  //通过dispatch,传递对应的action,调用对应的方法             <button onClick={()=>dispatch('sub')}>sub</button>         </div>     ) } export default Example5

5.useMemo

useMemo主要用来解决使用React hooks产生的无用渲染的性能问题。

只要使用useMemo,然后给她传递第二个参数,参数匹配成功,才会执行。

1.在父组件里面,传递对应需要的参数

import React , {useState,useMemo} from 'react'; function Example7(){     const [one , setOne] = useState('第一个的状态')     const [two , setTwo] = useState('志玲待客状态')     return (         <>             <button onClick={()=>{setOne(new Date().getTime())}}>第一个</button>             <button onClick={()=>{setTwo(new Date().getTime())}}>第二个</button>             <ChildComponent name={one}>{two}</ChildComponent>         </>     ) }

2.父组件调用子组件

function ChildComponent({name,children}){     function changeXiaohong(name){         return name     }  const actionXiaohong = useMemo(()=>changeXiaohong(name),[name])     return (         <>             <div>{actionXiaohong}</div>             <div>{children}</div>         </>     ) }

6.useRef

用useRef获取React JSX中的DOM元素,获取后你就可以控制DOM的任何东西了。但是一般不建议这样来作,React界面的变化可以通过状态来控制

import React, { useRef } from 'react' function Example8(){     const inputRef  = useRef(null)     const onButtonClick=()=>{         inputRef.current.value='THIS IS INPUT'         console.log(inputRef);     }     return(         <div>             <input type="text" ref={inputRef}/>             <button onClick = {onButtonClick}>显示</button>         </div>     ) } export default Example8

保存普通变量

import React, { useRef,useState } from 'react' function Example8(){     const inputRef  = useRef(null)     const onButtonClick=()=>{         inputRef.current.value='THIS IS INPUT'         console.log(inputRef);     }      const [state, setstate] = useState('inputValue')  //声明一个变量     return(         <div>             <input type="text" ref={inputRef}/>             <button onClick = {onButtonClick}>显示</button>             <input value={state} type="text" onChange={(e)=>setstate(e.target.value)}/>  //绑定对应的值以及绑定onChange事件         </div>     ) } export default Example8

以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。