我正在使用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中,当前处理状态的首选方式是什么。
答案 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);
}