鉴于此..
const [question, setQuestion] = useState({})
question
可以包含标题和说明。
即
{
title: 'How to use useState with {}?',
decription: 'given this..`const [question, setQuestion] = useState({})`and `question` can contain a title and a description. I.E. { title: 'How to use useState with {}?', decription: '' }How can the title and description be set independently with `setQuestion`?'
}
如何通过setQuestion
独立设置标题和描述?
你从useState()
获得的setter函数期望传递参数,这将完全取代旧状态。因此,不能仅使用它来更新标题,而不同时传入所有其他属性。
但是您可以从现有状态对象派生一个新的状态对象,然后将整个对象传递给setQuestion()
setQuestion({
...question,
title: "New title",
})
在这种情况下,我喜欢做的一件事是改用React.useReducer
钩子:
function App() {
const initialState = {
title: 'My title',
description: 'My description'
}
const [state, setState] = React.useReducer(
(p, n) => ({ ...p, ...n }),
initialState
)
return (
<div>
<p>{state.title}</p>
<p>{state.description}</p>
<button onClick={() => setState({ description: 'New description' })}>
Set new description
</button>
</div>
)
}
这样,您只需更改所需的属性,而不必处理复制旧状态对象并基于旧值和新值创建新状态对象。
此外,如果您刚开始使用hook
s,它可能看起来更熟悉,因为与类组件中的this.setState()
调用相似。
下面是一个演示此方法的小示例:
- 例
如果这是您使用的常见模式,那么我建议您编写自己的钩子来实现您想要的功能。
如果这是一次性的事情,那么您可以使用对象传播运算符来相当干净地完成它:
setQuestion({
...question,
title: 'updated title',
});
这是它被拉到一个单独的钩子中的样子:
const useMergeState = (initial) => {
const [state, setState] = React.useState(initial);
const mergeState = React.useCallback((update) => setState({...state, ...update}));
return [state, mergeState];
};
官方文档 说:
既将所有状态放在单个 useState 调用中,又具有 每个字段的使用状态调用都可以工作。但是,组件往往是大多数 当您在这两个极端之间找到平衡时可读,并且分组 将相关状态分成几个独立的状态变量。
例如:
const [position, setPosition] = useState({ left: 0, top: 0 });
const [size, setSize] = useState({ width: 100, height: 100 });
如果状态逻辑变得复杂,我们建议使用化简器或自定义 Hook对其进行管理。
另外,请记住,如果您在useState({}(钩子中使用任何状态对象,与经典的this.setState不同,更新状态变量总是替换它而不是合并它,因此您需要扩展以前的状态以免丢失他的一些属性,例如:setResource(…resource, name: ‘newName’);
setQuestion({
title: 'YOUR_TITLE',
description: 'YOUR_DESCRIPTION',
id: '13516',
})
无法编辑状态。您需要始终设置新值。因此,它可以替换为点差运算符,如下所示。
setQuestion({
...question,
title: 'new title'
})
或
const newQuestion = { ...question, title: 'new title }
setQuestion(newQuestion)