您现在的位置是:网站首页> 编程资料编程资料
react中(含hooks)同步获取state值的方式_React_
2023-05-24
369人已围观
简介 react中(含hooks)同步获取state值的方式_React_
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
import {useState} from "react"; export default function Pre04SetStateSync() { const [counter, setCounter] = useState(0) const add = () => { setCounter(counter + 1) console.log({counter}) } return <> 同步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 <> 同步SetState
请观察控制台
> } }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 <> 同步SetState
请观察控制台
> } }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 <> 同步SetState
请观察控制台
> } }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 <> 同步SetState
请观察控制台
> }react hooks常用方法
1.useState
function Example01(){ const [ count, setCount ] = useState(0) //声明 return( {count}
//读取 // 使用(修改) ) }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 测试解绑
; }3.useContext上下文传值
1.父组件:
const CountContext = createContext() //引入 function Example01(){ const [ count, setCount ] = useState(0) return( {count}
//使用包裹子组件传递值 ) }2.子组件:
function ChildContent(){ const context = useContext(CountContext) return( {context}
) }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( {count}
//通过dispatch,传递对应的action,调用对应的方法 ) } export default Example55.useMemo
useMemo主要用来解决使用React hooks产生的无用渲染的性能问题。
只要使用useMemo,然后给她传递第二个参数,参数匹配成功,才会执行。
1.在父组件里面,传递对应需要的参数
import React , {useState,useMemo} from 'react'; function Example7(){ const [one , setOne] = useState('第一个的状态') const [two , setTwo] = useState('志玲待客状态') return ( <> {two} > ) }2.父组件调用子组件
function ChildComponent({name,children}){ function changeXiaohong(name){ return name } const actionXiaohong = useMemo(()=>changeXiaohong(name),[name]) return ( <> {actionXiaohong} {children} > ) }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( ) } 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( 提示:
本文由神整理自网络,如有侵权请联系本站删除!
本站声明:
1、本站所有资源均来源于互联网,不保证100%完整、不提供任何技术支持;
2、本站所发布的文章以及附件仅限用于学习和研究目的;不得将用于商业或者非法用途;否则由此产生的法律后果,本站概不负责!
相关内容
- element-plus的自动导入和按需导入方式详解_vue.js_
- javascript实现登录框拖拽_javascript技巧_
- 关于Element-ui中table默认选中toggleRowSelection问题_vue.js_
- 使用vscode添加vue模板步骤示例_vue.js_
- unplugin-auto-import的配置以及eslint报错解决详解_vue.js_
- vue el-table中使用el-select选中后无效的解决_vue.js_
- JavaScript适配器模式的应用详解_javascript技巧_
- JSON schema配置规范使用教程_json_
- JavaScript单一职责原则深入分析_javascript技巧_
- Vue el-table 默认展开某一行的实例_vue.js_
点击排行
本栏推荐
