了解React useState()钩子

时间:2019-07-15 13:50:48

标签: javascript reactjs react-hooks setstate

我正在使用df1 <- data.frame(stock = c("Google, Yahoo", "Google", "Yahoo, Google", "Amazon, Google", "Google, Amazon")) 钩子来处理功能性的React组件。我对该挂钩的使用方式或背后的设计决策感到困惑。

我制作了一个Codepen示例来说明我的问题:

https://codepen.io/svenvandescheur/pen/ewwBwR

基于类的组件

在基于类的组件中,useState()仅使用传递给第一个参数的对象中的键来更新状态。如果状态已经包含不同的值,则将这些值保留在原处。

功能组件

我错误地认为,this.setState({foo: 'bar'})提供的setState()的语法和行为与useState()提供的对应语法和行为非常相似。但是,我注意到Component将替换整个状态,删除未传递的密钥。

可以通过以下方式解决此问题:使用扩展运算符将每次调用的整个状态传递给setState({foo: 'bar'}),然后再添加更改,例如:setState()

这感觉非常重复,在我的现实世界场景中甚至造成了一个错误,其中新状态被旧状态覆盖。

我的问题是,我是否正确地将setState({...state, foo: 'bar'})理解为useState()的{​​{1}},以及为什么选择了这种行为。在React中,当前处理状态的首选方式是什么。

2 个答案:

答案 0 :(得分:1)

您的理解是正确的。 setState将合并当前状态和新状态以创建新状态。 useState将采用给定的值并替换旧状态。

此行为看似不直观,但允许将原始值用作状态,例如字符串,数字和布尔值。

如果您需要更多状态,则只需添加更多useState。而且,如果您的状态更新逻辑变得有点复杂,则应该使用useReducer

答案 1 :(得分:0)

因此,如果您的状态是一个对象,您将需要创建一个新对象并使用它进行设置。这可能涉及传播旧状态。例如:

const [person, setPerson] = useState({ name: 'alice', age: 30 });

const onClick = () => {
  // Do this:
  setPerson(prevPerson => {
    return { 
      ...prevPerson, 
      age: prevPerson.age + 1 
    }
  })

}

也就是说,使用钩子你通常不再需要你的状态是一个对象,而是可以多次使用 useState 。如果您不使用对象或数组,则不需要复制,因此也不需要传播。

const [name, setName] = useState('alice');
const [age, setAge] = useState(30);

const onClick = () => {
  setAge(prevAge => prevAge + 1);
}