useState在onClick函数中设置方法和状态不变



一个状态属性是ReactNode,我想更改该属性,然后在一些onClick函数中获取属性值。

但我发现状态属性值并没有改变。

反应代码如下:

import React, { useState, useEffect } from 'react';
import { Button } from 'antd';
interface SomeData {
id?: number;
content?: React.ReactNode;
}
const Test = (): React.ReactElement => {
const [someData, setSomeData] = useState<SomeData>({});
const handleClick = (): void => {
console.log('click event', someData);
};
const loadData = (): void => {
const content = <Button onClick={handleClick}>button#1</Button>;
setSomeData({ id: 10, content, });
};
useEffect(() => { loadData() }, []);

return (
<div>
{someData.content}
<Button onClick={handleClick}>button#2</Button>
</div>
);
};

当我点击button#1时,函数handleClick控制台结果是click event {}

点击button#2,控制台结果为click event {id: 10, content: {…}}

为什么这两个相同的点击事件会产生不同的结果?

让我们看看发生了什么:

  1. 首次渲染Test时,someData是一个空对象,因此{someData.content}不渲染任何内容
  2. useEffect在第一次渲染后被调用(因为它有一个空的依赖项数组(。在那里,它在someData.content中保存了一个按钮,handleClick函数链接到该按钮
    注意:这个handleClick有自己的闭包,其中someData仍然是一个空对象,因为someData的更新还没有完成
  3. 当您单击button#1时,您正在调用带有闭包的handleClick,其中someData仍然是一个空对象
  4. 相反,当单击button#2时,由于每次都渲染button#2,因此每次渲染完成时,其handleClick闭包都会发生变化,因此这些handleClick中的someData会更新

如何解决此问题?这取决于你到底想做什么,因为我不明白。您希望在单击button#1时,将someData.id设置为1,然后执行某些操作吗?告诉我,我会尽力帮你的。

如果你想在点击按钮时"激活"你的函数"handleClick",你应该声明你的函数在函数"class"中。

示例:

import React, { Component, MouseEvent } from 'react';
export class Button extends Component {
handleClick(event: MouseEvent) {
event.preventDefault();
alert(event.currentTarget.tagName); // alerts BUTTON
}
render() {
return <button onClick={this.handleClick}>Click me</button>
}
}

来源:https://fettblog.eu/typescript-react/events/

相关内容

  • 没有找到相关文章

最新更新