Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 何时使用功能设置状态_Javascript_Html_Reactjs - Fatal编程技术网

Javascript 何时使用功能设置状态

Javascript 何时使用功能设置状态,javascript,html,reactjs,Javascript,Html,Reactjs,在过去的几天里,我一直在学习React,看一些教程和关于编写不同元素的不同方法的解释。然而,有一个我一直最感兴趣的功能是setState函数,用于更新/覆盖组件的state属性 例如,假设我有一个具有以下内容的类: class Photos extends React.Component { constructor() { super() state = { pictures: [] } } comp

在过去的几天里,我一直在学习React,看一些教程和关于编写不同元素的不同方法的解释。然而,有一个我一直最感兴趣的功能是
setState
函数,用于更新/覆盖组件的
state
属性

例如,假设我有一个具有以下内容的类:

class Photos extends React.Component {
    constructor() {
        super()
        state = {
            pictures: []
        }
    }

   componentDidMount() {
      // This is where the fetch and setState will occur (see below)
   }

    render() {
       return {
          <div className="container">
             {this.state.pictures}
          </div>
       }
    }
}

有人能解释一下这两种方法的优点吗?我希望将来与代码保持一致,处理道具和状态等,因此当然会首选最通用的方法。

TL;DR:功能性
setState
主要有助于在短时间间隔内触发多个
setState
s时期望正确的状态更新,而传统的
setState
会进行对账,并可能导致意外状态

请查看这篇精彩的文章,以获得清晰的理解

这里是

首先,您尝试在每种情况下执行不同的操作,在一种情况下分配图片,在另一种情况下连接图片

假设.state.pictures包含
[1,2,3]
,pics包含
[4,5,6]

this.setState(prevState => ({
   pictures: prevState.pictures.concat(pics)
}))
this.setState({pictures:pics})

在上述情况下,this.state.pictures将包含图片,即
this.state.pictures=[4,5,6]

this.setState(prevState => ({
   pictures: prevState.pictures.concat(pics)
}))
而在上述代码段中,this.state.pictures将包含以前的图片+图片,即
this.state.pictures=[1,2,3,4,5,6]

this.setState(prevState => ({
   pictures: prevState.pictures.concat(pics)
}))
无论哪种方式,您都可以调整它以满足您的API需求,如果它像分页响应,则最好将每个请求的结果串联起来,否则如果每次都获得整个数组,则只需分配整个数组即可

常规设置状态与功能设置状态

现在,您的问题可能主要是将
setState
用于对象还是函数

人们出于不同的原因使用它们,现在功能性的
setState
被称为是安全的,因为
React
执行一种称为协调过程的操作,在该过程中,当频繁或同时触发时,将
setState
内的多个对象合并,并一次性应用更改,有点像批处理。这可能会在下面这样的场景中导致一些意外的结果

示例:

increaseScoreBy3 () {
 this.setState({score : this.state.score + 1});
 this.setState({score : this.state.score + 1});
 this.setState({score : this.state.score + 1});
}
正如您希望分数增加3一样,React所做的是合并所有对象并只更新分数一次,即增加1

这是函数回调的亮点之一,因为函数上不会发生协调,执行下面的代码将按预期执行操作,即将分数更新3

increaseScoreBy3 () {
 this.setState(prevState => ({ score: prevState.score + 1 }));
 this.setState(prevState => ({ score: prevState.score + 1 }));
 this.setState(prevState => ({ score: prevState.score + 1 }));
}

首先,在你的例子中,这两种语法是完全不同的,你可能要寻找的是它们之间的区别

this.setState({pictures: this.state.picture.concat(pics)})

要理解为什么第二种方法是首选方法,您需要了解React在内部如何使用
setState()

React将首先将传递给
setState()
的对象合并到当前状态。然后就开始和解了。由于调用
setState()
可能不会立即更新您的状态

React可以将多个
setState()
调用批处理到单个更新中,以获得更好的性能

考虑一个简单的例子,为了理解这一点,您可以在函数中多次调用
setState()
,如下所示:

myFunction = () => {

   ...
   this.setState({pictures: this.state.picture.concat(pics1)})
   this.setState({pictures: this.state.picture.concat(pics1)})
   this.setState({pictures: this.state.picture.concat(pics1)})

   ...
}
在一个简单的应用程序中,这不是一个有效的用例,但随着应用程序变得复杂,多个
setState()
调用可能会从多个地方发生,执行相同的操作

因此,现在要执行有效的更新,React通过提取传递给每个
setState()
调用的所有对象来进行批处理,将它们合并在一起形成单个对象,然后使用该单个对象执行
setState()
。根据
setState()
文档:

这种形式的
setState()
也是异步的,同一周期内的多个调用可以批处理在一起。例如,如果您试图在同一周期内增加一个项目数量不止一次,则会产生以下等效结果:

Object.assign(
  previousState,
  {quantity: state.quantity + 1},
  {quantity: state.quantity + 1},
  ...
)
后续调用将覆盖同一周期中以前调用的值,因此数量只增加一次。如果下一个状态取决于当前状态,我们建议使用updater函数表单,而不是:

this.setState((state) => {
  return {quantity: state.quantity + 1};
});
有关详细信息,请参见:

-

因此,如果任何对象包含相同的键,则存储具有相同键的最后一个对象的键的值。因此,对于最后一个值,更新只发生一次

快速回答:


始终使用setState()的函数形式。

this.setState((state, props)=>({
    someValue: state.somevalue + 1
}));
这种方法不太容易出错,有助于消除一些很难找到的bug。即使有多个这样的更新,每个更新都是单独的函数调用,后续更新也不会导致某些更新丢失

另一种方法

this.setState({
someValue: state.somevalue + 1
});

如果频繁重复,可能会导致某些更新丢失,因为React会批量处理此类频繁更新

这两段代码不是等价的-第1版将
状态设置为。图片
设置为
图片
,而第2版将
状态设置为。图片
设置为上一个
状态。图片
结尾附加
图片
。@JoeClay,不,它不是,因为它不是回调函数,而是更新函数setState@ShubhamKhatri:哇,是的,你说得对。撤回了我的投票结果。但是,如果我在increaseScoreBy3中只有一个setState调用,
this.setState({score:this.state.score+1})
应该按预期工作吗?在这种情况下,使用函数回调不会使