React中很多地方需要用到数据,这在React中被叫做状态,我们需要一个专门管理状态的方法,于是state相关的就诞生了。state应该被要求有两个基本功能,一,能够存储一定的值,从而能被react使用,二,能够再它改变的时候被React监听到并且重新渲染。这里分别介绍一下在类和函数组件中state的写法:

类组件

class ClassComponent extends React.Component{
    constructor(props){
        super(props)
    } //可写可不写
    render(){
        return (
            //这里面可以写jsx语法
        )
    }
}

setState我们一般用来改变状态,在里面可以直接传一个要改变的对象,也可以传一个回调函数,注意,此时如果传入的是对象的话,React只是做了一层浅拷贝,而不是深拷贝,所以此时如果对象中有其他对象进行了改变React无法知道进行渲染。这个方法本质上是传入了一个新的值,将原先的值进行了覆盖,如果这个值跟原先的值一样,那么React就不会进行渲染。

React为什么要这么麻烦,不能直接修改值?因为在React中,有一个概念叫做可变性。React通过setState中的状态的改变知道哪些地方发生了,于是进行渲染,如果直接改变了state,React无法感知到,所以无法渲染。简单来说,它没有像vue一样双向数据绑定。

类组件中的constructor可写可不写,写上这个构造函数的作用主要有两个:

  • 为了给this.state赋值对象来初始化内部state的值
constructor(props){
    super(props)
    this.state = {n:12}
}

render(){
    return (
        <div>
                <h1>THE TIME IS {this.state.n}</h1>
        </div>
    )
}

注意这里不能写setState,以上的方法React也可以在外面设定,即

state = {n:12}

render(){
    return (
        <div>
            <h1>THE TIME IS {this.state.n}</h1>
        </div>
    )
}
  • 为事件处理函数绑定实例
constructor(props){
    super(props)
    this.addNum = function(){fn()}.bind(this)
}

render(){
    return (
        <button onClick={this.addNum}> 1</button>
    )
}

但是这种方法在React中也有新的方法替代了,代码如下:

addNum = ()=>{
    fn()
}

render(){
    return (
        <button onClick={this.addNum}> 1</button>
    )
}

所以上述的构造函数继承父类的方法根本没有必要写。

函数组件

import {useState} from "react"
function FunctionComponent(){
    const [data,setData] = useState("你要传入的初始值")
    return (
        <div>SHOW DATA {state}</div>
    )
}

这里的setData的作用跟setState类似,但是它只能用来改变data的状态,需要改变的时候传入一个回调函数。函数的参数是之前的值,返回一个要改变的值。这个方法本质是需要传入一个新的对象,来改变React之前对象的值。 对此还能简便的直接写改变的值,默认会对应到当前对象并且改变它的值
以上方法比原先的setState要简便不少,但是麻烦的是如果有多个数据,需要多次useState而不能一次性传入多个值。不过大多数情况下,数据管理的问题都是交给Redux来管理的,所以并不需要React本身来操心

setState的坑

在改变React组件状态的时候,经常遇到的问题是setState的值合并。看如下问题:

this.addNum = function () {
            this.setState({num:this.state.num 1})
            this.setState({num:this.state.num 1})
            this.setState({num:this.state.num 1})
        }.bind(this)

此时当addNum函数被触发的时候,num只加了1。并没有像我们想象的加了3。 对此,React本身的解释是

调用 setState 其实是异步的 —— 不要指望在调用 setState 之后,this.state 会立即映射为新的值

对此的解释是:

  1. 无论调用多少次setState,都不会立即执行更新。而是将要更新的state存入'_pendingStateQuene',将要更新的组件存入'dirtyComponent';
  2. 当根组件didMount后,批处理机制更新为false。此时再取出'_pendingStateQuene'和'dirtyComponent'中的state和组件进行合并更新;

简单来说,就是React执行时,为了提高性能,会把要更新的setState存入一个数组,当React本身的同步代码执行完毕,更新之前,将数组中的setState取出,然后进去渲染。上述代码中,我们因为将同步代码this.setState({num:this.state.num 1})加入了setState中,所以在批处理取出的时候,会产生合并,将众多的setState合并为一句话,从而只改变了1。因为这个机制,所以让setState像异步代码,但是其实它是同步执行的,此时我们如果将之前的同步代码改成异步的,我们就得到了我们想要的结果

this.addNum = function () {
            setTimeout(()=>{ this.setState({num:this.state.num 1}) },0)
            setTimeout(()=>{ this.setState({num:this.state.num 1}) },0)
            setTimeout(()=>{ this.setState({num:this.state.num 1}) },0)
        }.bind(this)

此时,值直接就加了3,因为异步代码会在代码执行的时候暂存。在所有同步代码执行完毕的时候再执行,此时批处理机制已经结束了,于是三个函数都被执行了,于是加了3 这是目前为止能想到的,如果以后有新的还会增加

以上就是React 三大属性之state的使用详解的详细内容,更多关于React 三大属性之state的资料请关注Devmax其它相关文章!

React 三大属性之state的使用详解的更多相关文章

  1. ios – React native链接到另一个应用程序

    如果是错误的,有人知道如何调用正确的吗?

  2. ios – React Native – 在异步操作后导航

    我正在使用ReactNative和Redux开发移动应用程序,我正面临着软件设计问题.我想调用RESTAPI进行登录,如果该操作成功,则导航到主视图.我正在使用redux和thunk所以我已经实现了异步操作,所以我的主要疑问是:我应该把逻辑导航到主视图?我可以直接从动作访问导航器对象并在那里执行导航吗?.我对组件中的逻辑没有信心.似乎不是一个好习惯.有没有其他方法可以做到这一点?

  3. 在ios中使用带有React Native(0.43.4)的cocoapods的正确方法是什么?

    我已经挖掘了很多帖子试图使用cocoapods为本地ios库设置一个反应原生项目,但我不可避免地在#import中找到了丢失文件的错误.我的AppDelegate.m文件中的语句.什么是使用反应原生的可可豆荚的正确方法?在这篇文章发表时,我目前的RN版本是0.43.4,而我正在使用Xcode8.2.1.这是我的过程,好奇我可能会出错:1)

  4. ios – React Native WebView滚动行为无法按预期工作

    如何确保滚动事件的行为与ReactNative应用程序中的浏览器相同?

  5. ios – React Native – BVLinearGradient – 找不到’React/RCTViewManager.h’文件

    谢谢.解决方法几天前我遇到了完全相同的问题.问题是在构建应用程序时React尚未链接.试试这个:转到Product=>Scheme=>管理方案…=>点击你的应用程序Scheme,然后点击Edit=>转到Build选项卡=>取消选中ParallelizeBuild然后点击标志添加目标=>搜索React,选择第一个名为React的目标,然后单击Add然后在目标列表中选择React并将其向上拖动到该列表中的第一个.然后转到Product=>再次清理并构建项目.这应该有所帮助.

  6. ios – React Native – NSNumber无法转换为NSString

    解决方法在你的fontWeight()函数中也许变成:

  7. ios – React native error – react-native-xcode.sh:line 45:react-native:command not found命令/ bin/sh失败,退出代码127

    尝试构建任何(新的或旧的)项目时出现此错误.我的节点是版本4.2.1,react-native是版本0.1.7.我看过其他有相同问题的人,所以我已经更新了本机的最新版本,但是我仍然无法通过xcode构建任何项目.解决方法要解决此问题,请使用以下步骤:>使用节点版本v4.2.1>cd进入[你的应用]/node_modules/react-native/packager>$sh./packager.s

  8. 反应原生 – 如何通过Xcode构建React Native iOS应用程序到设备?

    我试图将AwesomeProject应用程序构建到设备上.构建成功并启动屏幕显示,但后来我看到一个红色的“无法连接到开发服务器”屏幕.它表示“确保节点服务器正在运行–从Reactroot运行”npmstart“.看起来节点服务器已经运行,因为当我做npm启动时,我收到一个EADDRINUSE消息,表示该端口已经在使用.解决方法从设备访问开发服务器您可以使用开发服务器快速迭代设备.要做到这一点,你的

  9. 静音iOS推送通知与React Native应用程序在后台

    我有一个ReactNative应用程序,我试图获得一个发送到JavaScript处理程序的静默iOS推送通知.我看到的行为是AppDelegate中的didReceiveRemoteNotification函数被调用,但是我的JavaScript中的处理程序不会被调用,除非应用程序在前台,或者最近才被关闭.我很困惑的事情显然是应用程序正在被唤醒,并且它的didReceiveRemoteNotifi

  10. 如何为iOS的React Native设置分析

    所以我已经完成了一个针对iOS的ReactNative项目,但是我想在其中分析.我尝试了react-native-google-analytics软件包,但是问题阻止了它的正常工作.此外,react-native-cordova-plugin软件包只适用于Android,因此插入Cordova插件进行分析的能力现在已成为问题.我也没有Swift/ObjectiveC的经验,所以将完全失去GA的插入.有没有人有任何建议如何连接GoogleAnalytics的ReactNativeforiOS?

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部