Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.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
Reactjs React,是否绝对有必要将React状态视为不可变的?_Reactjs_Immutability - Fatal编程技术网

Reactjs React,是否绝对有必要将React状态视为不可变的?

Reactjs React,是否绝对有必要将React状态视为不可变的?,reactjs,immutability,Reactjs,Immutability,我正在做这样的事情,不知道是应该避免还是可以接受 因为将状态视为不可变是很复杂的 第一个版本是我通常做的 render() { var { blogs } = this.state var blogNodes = blogs.map((blog, i) => { return ( <div> {blog.name} <Checkbox checked={blog.checked}

我正在做这样的事情,不知道是应该避免还是可以接受

因为将状态视为不可变是很复杂的

第一个版本是我通常做的

render() {
  var { blogs } = this.state
  var blogNodes = blogs.map((blog, i) => {
    return (
      <div>
        {blog.name}
        <Checkbox
          checked={blog.checked}
          onChange={
            (e, {name, value, checked}) => {
              blog.checked = checked
              this.setState({blogs})
            }
          }
          />
      </div>
    )
    })                                                                                                                                                                                   
} ,  
render(){
var{blogs}=this.state
var blogNodes=blogs.map((blog,i)=>{
返回(
{blog.name}
{
blog.checked=选中
this.setState({blogs})
}
}
/>
)
})                                                                                                                                                                                   
} ,  
第二个版本似乎是更正确的版本

render() {
  var { blogs } = this.state                                                                                                                                                       
  var blogNodes = blogs.map((blog, i) => {                                                                                                                                          

  return (                                                                                                                                                                          
     <div>
        {blog.name}
        <Checkbox
          checked={blog.checked}
          onChange={
            (e, {name, value, checked}) => {
              blog.checked = checked
              var newState = update(this.state, {
                blogs: {
                  i: {
                    $set: {
                      checked: checked
                    }
                  }
                }
              })
              this.setState(newState)
            }
          }
          />
      </div>
    )
  })
}
render(){
var{blogs}=this.state
var blogNodes=blogs.map((blog,i)=>{
报税表(
{blog.name}
{
blog.checked=选中
var newState=update(this.state{
博客:{
一:{
$set:{
勾选:勾选
}
}
}
})
this.setState(newState)
}
}
/>
)
})
}
是否绝对有必要将react状态视为不可变的,还是仅仅出于性能原因

如果我必须将其视为不可变的,有没有比我的第二个版本更简单的方法来执行上述操作? 当我们手头上有索引(i)时,这将更加令人厌烦

是否绝对有必要将反应状态视为不可变的

这取决于你们所说的“绝对必要”是什么意思,但我认为可以肯定地说,在React if中改变状态是一个非常糟糕的主意。如果你继续这样做的话,你会朝自己的脚开枪的。性能调优是一个原因,但另一个原因很简单,如果不遵循React的API规则,您将获得不可预测的行为,例如无意中覆盖数据或以难以调试的方式破坏呈现

React是一个可预测的渲染周期:使用
setState()
对状态进行更改,这将在将来的某个时间触发具有最新状态的
render()

您的第二个示例仍然存在问题。首先,通过设置
blog.checked=true
,您仍然在状态中变异
blog
。其次,您将用
newState
替换整个状态。这是产生问题的原因,因为
setState()
只调度修补程序,所以您应该只替换实际正在更改的属性--
setState({blogs})
,否则您可能会与对
setState()
的其他调用冲突。最后,如果您正在访问当前的
状态
,您应该真正使用回调表单()来确保您所处的状态实际上是完全最新的版本

使用ES6 object spread,您可以通过以下方式执行此操作:

this.setState((prevState, props) => {
  const {blogs} = this.state;
  return {
    blogs: [
      ...blogs.slice(0, i), 
      { ...blogs[i], selected: true }
      ...blogs.slice(i)
    ]
  };
});
或者使用
map()
仅用索引替换一个元素:

this.setState((prevState, props) => {
  const {blogs} = this.state;
  return {
    blogs: blogs.map(
      (blog, index) => index == i ? { ...blog, selected: true } : blog
    )
  };
});

保持组件状态不变是绝对必要的吗?不,但是理解为什么应该这样做很重要,特别是如果在状态树中有嵌套(如您的示例),下面是原因

React会在所述组件的任何状态(或道具)更新时更新组件,React最好的部分是您可以使用shouldComponentUpdate()生命周期事件完全控制该更新的发生时间,因此。。如果您正在修改state对象,那么您必须执行一些称为深度公平检查的操作,以确定何时更新state,这将随着state对象内部嵌套的增多而变得更糟

现在想象一下,将您的状态保持为不可变对象,您最终得到了这个漂亮的状态对象,它是显式的、易于预测的,并且您可以相应地优化您的组件以获得更好的性能

第二,默认情况下做出反应不要进行深入的公平检查以查看状态或道具是否更新,因此你可能会听到他们告诉人们不要改变状态,就像其他人提到的那样

现在,对于实现任何react组件,请始终记住,保持状态最小是您可以获得的最佳react实践,因此最好只为组件提供渲染所需的值

onChange(event, i) {
 const target = event.target;
 const value = target.type === 'checkbox' ? target.checked : target.value;
 this.props.handleChange(this.props.blog, value)
}

render() {
  var { blog } = this.state                                                                                                                                                       
  return (                                                                                                                                                                          
     <div>
        {blog.name}
        <Checkbox
          checked={blog.checked}
          onChange={this.onChange}
          />
      </div>
    )
}

第二个也是错误的,您仍然将
blog.checked设置为true。是的,状态必须是不变的,否则就会有问题。而且也不要将代码内联到渲染中,将其放入函数中,这样至少会更容易处理。否则会更简单吗?这也是一个观点问题。如果您使用redux这样的状态处理程序,不变性是有意义的,因为它提供了调试工具。第二个示例是附加一个新博客,而不是替换现有的博客。检查我的答案。
handleChange(blog, value) {
 this.setState({
   blogs: [
    ...blogs,
    {...blog,  selected: value}
   ]
 })
}