关于前端开发,我最开心的事情就是总有新的东西能够学习。但咱们可能一生都在掌握各类编程语言、库和框架,但仍然一无所知。前端
由于咱们都在学习,这也意味着咱们都容易犯错误。不要紧,咱们的目的是变得更好。若是你犯了一个错误并从中吸收教训,你就作得很好!可是若是你没有学到任何新的东西,而且不断重复犯一样的错误,emmm。。。可能你的职业生涯就会停滞不前。react
本着这种精神,下面是我在 CodeReview 初级开发同窗时常常看到的三个错误。咱们一块儿来 check 一下,而后讨论如何改正它。web
在更新 React 组件状态时,最重要的是调用 setState 方法去更新,而且传入的对象是一个新的副本,而不是直接修改以前的状态。若是你错误地修改了组件的状态,React Diff 算法将没法捕获更改,并且你的组件也没法正确地更新。让咱们来看一个例子。算法
假设你有这样的状态:编程
this.state = {
colors: ['red', 'green', 'blue'] } 复制代码
如今你想要给这个数组添加颜色:数组
// 方法1:
this.state.colors.push('yellow’) // 方法2: this.state.colors = [...this.state.colors, 'yellow’] 复制代码
这两种方法都是错误的!在更新类组件中的状态时,必须使用 setState 方法,而且应该注意不要改变原始对象。下面是添加元素到数组的正确方法:框架
this.setState(prevState => ({ colors: [...prevState.colors, 'yellow'] }))
复制代码
setState 有两种使用方法。第一种方法是传入一个对象做参数。第二种方法是传入一个函数做参数。你知道这两种方法分别应该在何时使用吗?异步
例如,若是你有一个能够启用或禁用的按钮,那么你可能会有一个名为 isDisabled 的状态,其中包含一个布尔值。若是你想切换这个按钮的状态,你可能很会写这样的一段代码:编程语言
// setState 使用一个对象做参数
this.setState({ isDisabled: !this.state.isDisabled }) 复制代码
那么,这有什么问题呢?问题在于 React 状态更新能够批处理(batchUpdate),这意味着多个状态更新能够在一个更新周期中发生。若是你的更新将被批处理,而且你对 isDisabled 状态有多个更新,那么最终结果可能不是你所指望的。编辑器
更新状态的更正确的方法是提供前一个状态的函数做为参数:
this.setState(prevState => ({ isDisabled: !prevState.isDisabled }))
复制代码
如今,即便你的状态更新被批处理,而且有多个更新都在操做 isDisabled 状态,但每一个更新都依赖于正确的先前状态,所以你老是会获得预期的结果。
相似的递增计数器也是如此。
// 不要这样作
this.setState({ counterValue: this.state.counterValue + 1 }) // 正确的写法 this.setState(prevState => ({ counterValue: prevState.counterValue + 1 })) 复制代码
最后,记住 setState 是一种异步方法是很重要的。
初学者能够先理解成异步,但严格意义上说,须要区分条件来看。
如:在 React 内部生命周期以及事件处理函数中是异步的。
如:在 setTimeout 函数中调用 setState 倒是同步的。
举个例子,假设咱们有一个以下状态的 React 组件:
this.state = { name: 'John' }
复制代码
有一个方法更新状态,并将新的状态打印到控制台上:
this.setState({ name: 'Matt' })
console.log(this.state.name) 复制代码
你可能认为打印出来的会是 Matt
,但它不会! 它会打印 John
!
这是由于 setState 是异步的。这意味着执行到 setState 时,会把真正更新的操做放在异步队列中去执行,但它下面的同步代码将当即执行,因此打印出来的 state 就不是最新的。
若是你想拿到更新完成后的最新状态,React 容许你传一个回调函数,该函数会在更新完成后运行。
this.setState({ name: 'Matt' }, () => console.log(this.state.name))
复制代码
问题解决了! 如今它能够正确地记录 Matt
了。
好了!以上就是今天给你们分享的 React 中的三个常见错误及其纠正方法。记住,犯错误是正常的,但要避免犯一样的错误。你在学习、我在学习、咱们都在学习。让咱们继续学习,一块儿变得更好。