在react中正确修改state

13 篇文章 0 订阅

一,在react中可以通过this.state.{属性}的方式直接获取state,但当我们想要修改state的时候有许多的坑需要注意,以下 为三种常见的陷阱:

不能直接修改state。

组件直接修改state,并不会重新触发render。列如:

this.state.title='React';

正确修改方式是:

this.setState({title:'React'});
state的更新是异步的

调用setState时,组件state并不会立即改变,而是把要修改的状态放入事件队列中,而react优化了真正的执行时机,并且出于本身性能原因,可能会将多次setState的状态修改合并成一次状态修改。因此不要依靠当前的state计算下一个state,因为当真正执行状态修改时,有时候依赖的this.state并不能保证是最新的state,因为react本身会把多次state合并成一次,这时this.state还是旧state,因此也不能依赖当前的props计算下一个状态,因为props的更新也是异步。如:对于react常用的列子中有一个点击加号数值增加一的操作,点击一次+,数量会加1,如果连续点击两次,还是会加1,这是在react合并修改为一次的情况下,相当与执行了如下代码:

Object.assign(
previousState,
{quantity:this.state.quantity+1},
{quantity:this.state.quantity+1},
)

于是后面覆盖前面的操作,最终数值只加1,此时可以使用另一个函数作为参数的setState,这个函数有两个参数,第一个参数是本次组件修改前的状态,第二个参数是当前最新的props。

正确修改方式是:

this.setState((preState, props)=>counter:preState.quantity+1)
state的更新是一个合并的过程

 

当调用ssetState修改组件的状态时,只需要传入发生改变的state,而不是完整的state,因为组件state的更新时一个合并的过程,列如,一个组件的状态为:

this.state={

title:'React',

content:'React is an wondeful JS library'

}

注:当只需要修改title时,将修改的title传给setState即可:

 

this.setState({title:'ReactJs'});

react会合并最新的title到原来的状态,同时保留原来状态的content,最终合并state为:

this.state={
title:'ReactJs,
content:''React is an wondeful Js library
}

 

二,state与不可变对象

react官方把state当成不可变对象,一方面直接修改this.state,组件并不会重新render;另一方面,state中包含的所有状态都应该是不可变的对象,当state当中的某一个状态发生变化时,应该重新创建这个状态对象,而不是直接修改原来的state状态,那么当状态发生变化时,如何去创建新的状态呢,我们根据状态类型可以分为下面三种情况:

 

状态类型为不可变类型(number,string,bool,bull,undefined)

这种情况最简单,因为状态是不可变类型,所以直接给要修改的状态赋一个新值即可,列如下面我们要修改的count为number型,title(string),success(bool)三个状态:

 

this.setState({
count:1,
title:'React',
success:true
})

 

状态类型为数组

假如有一个数组类型的状态books,当想books中增加一本书时,既可使用数组的concat方法或者es6的扩展语法(apread syntax)

方法一:使用preState,concat创建新数组

 

 this.setState((preState)=>books:preState.books.concat(['React Guide']))

 

方法二:ES6 spread syntax

 

this.setState(preState=>books:[...preState,''React Guide])

 

当我们从books中截取部分元素作为新状态时,可以用数组的slice方法:

 

this.setState(preState=>books:preState.books.slice(1,3))

 

当从books中过滤部分元素后,作为新状态时,可以使用filter方法:

 

 this.setState(preState => {
        books: preState.books.filter(item => {

        return item != 'React';

        })
    })

 

注意:不要使用push,pop,shift,unshift,splice登方法修改数组类型的状态,因为这些方法都是在原数组的基础上修改的,而concat,slice,filter会返回一个新的数组。

 

方法三:状态的类型是普通对象(不包含:string,array)

 

使用es6的Object.assgin()方法

 

this.setState({

onwer:Object.assgin({},preState.onwer,{name:'Jason'});

})

 

使用对象扩展语法(Object spread properties):

this.setState(preState=>{
owner:{...preState.owner,name:'Jason'}
})

 

总结:

创建新的状态的关键是,避免使用会直接修改原对象的方法而是使用可以返回一个新对象的方法,当然可以使用Immutable的JS库(Immutable.js)实现类似的效果。

 

思考:

为什么React推荐组件状态的修改时不可变对象呢?

  1. 不可变对象的修改会返回一个新的对象,不用担心原对象在不小心的情况下修改导致的错误,方便程序的管理和调试
  2. 处于性能的考虑,对象组件的状态是不可变对象时,在组件的shouldComponentUpdate方法中仅需要比较前后两次状态对象的引用就可以判断状态是否真的改变,从而避免不必要的render调用

三:除了以上方法修改react组件的状态之外,我们还经常会用到replaceState改变组件的状态

 

replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除。使用语法:

replaceState(object nextState,[, function callback])

nextState,将要设置的新状态,该状态会替换当前的state。

callback,可选参数,回调函数。该函数会在replaceState设置成功,且组件重新渲染后调用。

如:

 class App extends React.Component{

     constructor(props);

      this.state={

      count:1

      title:'数字计算'

      }

}

handleClick=()=>{

  this.replaceState({

    count:this.state.count+1

  })

}

render(){
    return(
      <button onClick={this.onClick}>点我</button>
      )
  }

}

 

结果为:

 

{
count:1
}
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: 在Reactstate指的是组件内部维护的一个状态,它可以存储组件的数据,控制组件的行为和渲染。state是一个对象,可以通过this.state来访问它,通过this.setState来更新它。当组件的state发生改变时,React会自动重新渲染组件,以反映出最新的状态。通过使用state,我们可以构建出可交互的、动态的React组件。 ### 回答2: 在ReactState是一种用于存储组件内部数据的机制。它是一个JavaScript对象,用于记录和控制组件的状态。State可以存储任何类型的数据,如字符串、数字、数组、对象等。 StateReact非常重要,它使得组件能够根据内部数据的变化来更新和重新渲染UI。当State发生变化时,React会自动调用组件的render方法,并根据新的State值重新渲染组件和子组件。 通过使用State,我们可以控制组件的动态行为和显示效果。当我们需要在组件内部跟踪和管理数据时,State提供了一种便捷的方式。我们可以通过setState()方法来更新State的值,以响应用户的交互或其他事件。 使用State时要注意,State是组件私有的,只能在组件内部访问和修改。在组件定义State时,应该考虑到它的使用范围,并尽量避免直接修改State值,而应该使用setState()方法来更新State,以保证React正确地处理State的变化。此外,由于State的更新可能是异步的,应该谨慎处理State的值,以避免出现意外的结果。 总而言之,StateReact一种用于存储和管理组件内部数据的机制,它能使组件能够根据数据变化来更新和重新渲染UI,提供了一种便捷的方式来处理动态行为和显示效果。 ### 回答3: 在Reactstate是一个用于存储和管理组件内部数据的对象。 State用于存储组件内部的数据,并在异步事件触发后,可以更新组件的显示内容。在React,当state的值发生变化时,React会自动重新渲染组件,确保页面显示的内容与最新的state值保持一致。 State是私有的,每个组件都有自己的state,并且只能在组件内部进行访问和修改,无法从组件外部直接访问或修改state。这种封装性有助于提高组件的可维护性和可重用性。 State的初始化通常在组件的构造函数完成,可以通过setState()方法更新state的值。setState()方法接受一个新的state对象作为参数,并将其合并到当前的stateState的更新可能是异步的,React会将多个setState()调用合并成一个单一的更新,以提高性能。因此,在更新state时,应该使用函数形式的setState(),而不是直接修改this.state的方式,以确保对state修改正确合并。 总之,stateReact用于管理组件内部数据的对象,它的特点包括封装性、异步更新和自动重渲染。通过合理使用state,可以实现动态的页面内容和交互。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值