React 改变state必须知道的知识点

react可以通过this.state.xx的方式直接获取state,但是当我们修改state的时候,往往有许多的坑。

1. 不能直接修改state

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

 //错误
this.state.title='attend';

//正确
this.setState({title:'attend'});
2. state的更新是异步的

调用setState时,组件state并不会立即改变,只是把要修改的状态放入事件队列当中,为了弥补这个问题,使用另一种 setState() 的形式,接受一个函数。这个函数将接收前一个状态作为第一个参数,应用更新时的 props 作为第二个参数,代码如下:

//正确
this.setState((prevState, props)=>({
	counter: prevState.counter + 1
}))
3. state的更新是一个合并的过程

当调用setState()修改组件的状态时,只需要传入发生改变的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状态,那么当状态发生变化时,如何去创建新的状态呢,我们根据状态类型可以分为下面三种情况:

  1. 状态类型为不可变类型
    number、string、boolean、null、undefined
    这种情况最简单,因为状态是不可变类型,所以直接给要修改的状态赋一个新值即可,例如我们要修改的count为number型,title(string),success(boolean)三个状态:
this.setState({
	count:1,
	title:'React',
	success:true
})
  1. 状态类型为数组
    假如有一个数组类型的状态books,当向books中增加一本书时。
//方法一:使用preState,concat创建新数组
 this.setState((prevState)=>({
	books: prevState.books.concat(['React Guide'])
}))

//方法二:ES6 spread syntax
this.setState(prevState=>({
	books:[...prevState,'React Guide']
}))

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

this.setState(prevState=>({
	books: prevState.books.slice(1,3);
}))

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

this.setState(prevState=>({
	books: prevState.books.filter(item=>{
	  return item!='React';
	})
}))

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

  1. 状态的类型是普通对象

(1) 使用es6的Object.assgin()方法

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

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

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

创建新的状态的关键是避免使用直接修改原对象的方法,这种方法在vue中称为变异方法,而是使用可以返回一个新对象的方法,当然可以使用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设置成功,且组件重新渲染后调用。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是React中常用的一些知识点: 1. 组件:React将用户界面拆分为可重用的组件,组件是构建React应用的基本单元。组件可以是函数组件或者类组件。 2. JSX:JSX是一种类似于HTML的语法扩展,可以在JavaScript代码中编写类似HTML的结构。它允许我们以声明式方式描述UI组件的结构。 3. Props:Props是组件的属性,用于传递数据和配置参数给组件。通过props,我们可以向子组件传递数据并进行组件之间的通信。 4. StateState是用于存储和管理组件内部的数据的对象。当state发生变化时,React会自动重新渲染组件,并更新相应的视图。 5. 生命周期:React组件具有生命周期方法,这些方法在组件的不同阶段被调用,例如组件被创建、更新、卸载等。 6. Hooks:Hooks是React 16.8版本引入的特性,它允许我们在无需编写类组件的情况下使用状态和其他React特性。常用的Hooks包括useState、useEffect、useContext等。 7. 条件渲染:React允许我们根据条件来渲染不同的内容或组件。常用的条件渲染方式包括if语句、三元表达式和逻辑与(&&)运算符等。 8. 列表渲染:React提供了map方法来遍历数组或者列表,动态生成列表项。通过列表渲染,我们可以根据数据动态生成多个相似的组件。 9. 表单处理:React提供了一些事件和处理函数来方便地处理表单的输入和提交。通过onChange事件,我们可以监听表单元素的值变化,并将其保存到组件的state中。 10. 组件通信:React中的组件通信可以通过props、状态提升、上下文(Context)和全局状态管理工具(如Redux)等方式来实现。 这些是React中常用的知识点,当然还有更多深入的内容和特性可以学习和掌握。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值