一个状态属性是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: {…}}
。
为什么这两个相同的点击事件会产生不同的结果?
让我们看看发生了什么:
- 首次渲染
Test
时,someData
是一个空对象,因此{someData.content}
不渲染任何内容 useEffect
在第一次渲染后被调用(因为它有一个空的依赖项数组(。在那里,它在someData.content
中保存了一个按钮,handleClick
函数链接到该按钮
注意:这个handleClick
有自己的闭包,其中someData
仍然是一个空对象,因为someData
的更新还没有完成- 当您单击
button#1
时,您正在调用带有闭包的handleClick
,其中someData
仍然是一个空对象 - 相反,当单击
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/