ReactJS - 新的 useState React 钩子中的 prevState?

IT技术 reactjs react-hooks
2021-04-02 00:05:00

我真的很喜欢新的React 钩子,我经常在我正在从事的项目中使用它们。我遇到了一种情况,我想钩子中使用prevStateuseState,但我不确定如何做到这一点。

我试过这样的事情,但它无法编译。

const [ someState, setSomeState ] = useState( new Map() )
setSomeState( prevState.someState.set( key, value ) )

(顺便说一下,这是映射一组复选框以跟踪被选中的复选框)

我正在尝试在此处遵循此示例,但未使用该setState功能。

谢谢您的帮助!

5个回答

对于对象,您可以使用扩展运算符prevState在您的setState调用中使用

const [object, setObject] = useState({
  firstKey: '',
  secondKey: '',
});

setObject((prevState) => ({
  ...prevState,
  secondKey: 'value',
}));

// object = {
//   firstKey: '',
//   secondKey: 'value',
// }

下面的代码片段显示了一个prevState用于设置对象状态的示例

我终于明白了如何在这个片段中使用这个 prevstate。谢谢
2021-06-07 00:05:00
我相信这会降低性能,因为 React 认为所有状态条目都设置为新的东西。此外,您正在克隆一个数组,这也会导致具有许多条目的状态的性能急剧下降。
2021-06-10 00:05:00

为了使用Maps,您需要在操作值之前克隆它。否则,它会改变原始的Map并且 React 不处理 mutatable state

const handleChange = useCallback(({ target: { name, checked } }) => {
  setCheckbox(prevState => {
    return new Map(prevState).set(name, checked);
  });
}, []);

更新的工作示例

编辑多复选框处理程序

更新了答案以包含一个工作Map示例。虽然这有效,但它的性能可能不如其他替代方案(尤其是当它Map变大时)。
2021-06-05 00:05:00

state updaterfromuseState提供了一个回调模式,它返回您可以用来更新当前状态的先前状态

const [ someState, setSomeState ] = useState( new Map() )
setSomeState(prevState => prevState.set( key, value ) )
@EricBurel 你并不总是需要使用函数式 setState 但有时它真的很有用。这篇文章解释了类组件的一些细节,但同样适用于功能组件。在额外的功能状态更新中,钩子对于避免关闭问题也非常有用,因为你可以保证获得最新的状态
2021-05-26 00:05:00
你可能正在使用prevState.someState.set( key, value ) 而不是prevState.set( key, value )
2021-05-29 00:05:00
只是为了确认:为什么使用回调中的状态而不是someState避免混乱的并发更新?我只是经常看到这个,但从来没有出现过的技术解释。
2021-06-02 00:05:00
嘿,我试过这个,但我收到了这个错误Cannot read property 'set' of undefineduseState挂钩的限制?
2021-06-13 00:05:00
2021-06-20 00:05:00

您已经在 destructed 变量中获得了先前的状态: someState

所以你可以这样做:

const [ someState, setSomeState ] = useState( new Map() )
setSomeState( someState.set( key, value ) )
不知道 OP,但这解决了我面临的一个问题。谢谢。而且很聪明!
2021-05-24 00:05:00

用这个

const [setSome, setSomeState] = useState({thing: 'loding', count: 1});
setSomeState(prev => ({...prev, count: prev.count + 1}));