哪个更有效:对经常更新的对象使用多个 useState 挂钩或一个 useState?
Which is more efficient: use of many useState hooks or one useState for often updated object?
我正在尝试了解哪种使用 useState 钩子的方式是更好的做法。请考虑这两个简单的 React 组件示例:
多个 useState 挂钩
const Cake = () => {
const [topping, setTopping] = useState('');
const [icing, setIcing] = useState('');
const [fruit, setFruit] = useState('');
const [base, setBase] = useState('');
const [cake, setCake] = useState({topping: '', icing: '', fruit: '', base: ''});
const createCake = () => {
setCake({
topping: topping,
icing: icing,
fruit: fruit,
base: base
});
console.log(cake);
}
return (
<div>
<p>Choose from possible toppings:</p>
<Select options={toppings} onChange={e => setTopping(e.target.value)} value={topping}/>
<p>Choose from possible icings:</p>
<Select options={icings} onChange={e => setIcing(e.target.value)} value={icing}/>
<p>Choose from possible fruits:</p>
<Select options={fruits} onChange={e => setFruit(e.target.value)} value={fruit}/>
<p>Choose from possible bases:</p>
<Select options={bases} onChange={e => setBase(e.target.value)} value={base}/>
<button onClick={createCake}>Create</button>
</div>
);
}
export default Cake;
一个useState钩子,但是整个对象的所有属性都更新了多次
从 'react' 导入 React,{useState};
const Cake = () => {
const [cake, setCake] = useState({topping: '', icing: '', fruit: '', base: ''});
const setTopping = (e) => {
setCake({
topping: e.target.value,
icing: cake.icing,
fruit: cake.fruit,
base: cake.base
});
};
const setIcing = (e) => {
setCake({
topping: cake.topping,
icing: e.target.value,
fruit: cake.fruit,
base: cake.base
});
};
const setBase = (e) => {
setCake({
topping: cake.topping,
icing: cake.icing,
fruit: cake.fruit,
base: e.target.value
});
};
const setFruit = (e) => {
setCake({
topping: cake.topping,
icing: cake.icing,
fruit: e.target.value
base: cake.base
});
};
const createCake = () => {
console.log(cake);
};
return (
<div>
<p>Choose from possible toppings:</p>
<Select options={toppings} onChange={setTopping}/>
<p>Choose from possible icings:</p>
<Select options={icings} onChange={setIcing} value={icing}/>
<p>Choose from possible fruits:</p>
<Select options={fruits} onChange={setFruit} value={fruit}/>
<p>Choose from possible bases:</p>
<Select options={bases} onChange={setBase} value={base}/>
<button onClick={createCake}>Create</button>
</div>
);
}
export default Cake;
这个选项中哪个更好?这里有什么 mistakes/bad 我以后应该避免的做法吗?
这取决于值如何变化。如果它们一起改变,则将它们放在一个变量中,如果不是,则拆分对象。
钩子的 setState 和 classes 的一个主要区别是:
对于 class 个组件 this.setState
自动合并状态对象。
this.setState({ topping: 'newTopping' });
但是在钩子中,你必须用一个新的状态变量替换状态变量并且没有合并。
这就是您会看到 spread operator
...
用于创建对象副本然后用 setState
替换对象的原因。
setCake(cake => { ...cake, topping : 'newTopping' });
所以如果你的状态在逻辑上应该被组合在一起并且不是很嵌套,你可以将它们放在一起。
hooks 常见问题解答中有一个 section,直接回答了这个问题。直接来自文档:
we recommend to split state into multiple state variables based on which values tend to change together.
您可以根据您的用例选择任何方法。但根据官方文档,建议将状态拆分为多个状态变量,根据哪些值趋向于一起变化。
这里有个link说的单变量或者多变量的使用你也可以参考
https://reactjs.org/docs/hooks-faq.html#should-i-use-one-or-many-state-variables
我建议如果你是单机useState,那么尝试写代码如下:
setCake((cake) => ({
...cake,
fruit: e.target.value
}));
您可以使用其中任何一种方法来更新状态,但这最终取决于您的用例。在实际应用程序中,您会遇到这两种情况。
只需确保您使用的是哪种组件类型,即:class 或功能组件。 Class组件this.setState
自动合并状态对象而功能组件需要spread operator(...)
合并剩余状态
我正在尝试了解哪种使用 useState 钩子的方式是更好的做法。请考虑这两个简单的 React 组件示例:
多个 useState 挂钩
const Cake = () => { const [topping, setTopping] = useState(''); const [icing, setIcing] = useState(''); const [fruit, setFruit] = useState(''); const [base, setBase] = useState(''); const [cake, setCake] = useState({topping: '', icing: '', fruit: '', base: ''}); const createCake = () => { setCake({ topping: topping, icing: icing, fruit: fruit, base: base }); console.log(cake); } return ( <div> <p>Choose from possible toppings:</p> <Select options={toppings} onChange={e => setTopping(e.target.value)} value={topping}/> <p>Choose from possible icings:</p> <Select options={icings} onChange={e => setIcing(e.target.value)} value={icing}/> <p>Choose from possible fruits:</p> <Select options={fruits} onChange={e => setFruit(e.target.value)} value={fruit}/> <p>Choose from possible bases:</p> <Select options={bases} onChange={e => setBase(e.target.value)} value={base}/> <button onClick={createCake}>Create</button> </div> ); } export default Cake;
一个useState钩子,但是整个对象的所有属性都更新了多次
从 'react' 导入 React,{useState};
const Cake = () => { const [cake, setCake] = useState({topping: '', icing: '', fruit: '', base: ''}); const setTopping = (e) => { setCake({ topping: e.target.value, icing: cake.icing, fruit: cake.fruit, base: cake.base }); }; const setIcing = (e) => { setCake({ topping: cake.topping, icing: e.target.value, fruit: cake.fruit, base: cake.base }); }; const setBase = (e) => { setCake({ topping: cake.topping, icing: cake.icing, fruit: cake.fruit, base: e.target.value }); }; const setFruit = (e) => { setCake({ topping: cake.topping, icing: cake.icing, fruit: e.target.value base: cake.base }); }; const createCake = () => { console.log(cake); }; return ( <div> <p>Choose from possible toppings:</p> <Select options={toppings} onChange={setTopping}/> <p>Choose from possible icings:</p> <Select options={icings} onChange={setIcing} value={icing}/> <p>Choose from possible fruits:</p> <Select options={fruits} onChange={setFruit} value={fruit}/> <p>Choose from possible bases:</p> <Select options={bases} onChange={setBase} value={base}/> <button onClick={createCake}>Create</button> </div> ); } export default Cake;
这个选项中哪个更好?这里有什么 mistakes/bad 我以后应该避免的做法吗?
这取决于值如何变化。如果它们一起改变,则将它们放在一个变量中,如果不是,则拆分对象。
钩子的 setState 和 classes 的一个主要区别是:
对于 class 个组件 this.setState
自动合并状态对象。
this.setState({ topping: 'newTopping' });
但是在钩子中,你必须用一个新的状态变量替换状态变量并且没有合并。
这就是您会看到 spread operator
...
用于创建对象副本然后用 setState
替换对象的原因。
setCake(cake => { ...cake, topping : 'newTopping' });
所以如果你的状态在逻辑上应该被组合在一起并且不是很嵌套,你可以将它们放在一起。
hooks 常见问题解答中有一个 section,直接回答了这个问题。直接来自文档:
we recommend to split state into multiple state variables based on which values tend to change together.
您可以根据您的用例选择任何方法。但根据官方文档,建议将状态拆分为多个状态变量,根据哪些值趋向于一起变化。
这里有个link说的单变量或者多变量的使用你也可以参考
https://reactjs.org/docs/hooks-faq.html#should-i-use-one-or-many-state-variables
我建议如果你是单机useState,那么尝试写代码如下:
setCake((cake) => ({
...cake,
fruit: e.target.value
}));
您可以使用其中任何一种方法来更新状态,但这最终取决于您的用例。在实际应用程序中,您会遇到这两种情况。
只需确保您使用的是哪种组件类型,即:class 或功能组件。 Class组件this.setState
自动合并状态对象而功能组件需要spread operator(...)
合并剩余状态