设置后立即访问 React State

2025-06-08

设置后立即访问 React State

照片由CelsoUnsplash上拍摄

当我浏览 Stack Overflow 问题时,我注意到许多错误都是由于在设置状态值后尝试访问它而导致的。

Stack Overflow 上的一个示例问题。

我曾多次因为没有意识到setState异步操作而陷入困境。

那么我们如何在设置之后立即访问状态值呢?

😬 问题重现

clickCounts下面是同步设置状态值后立即访问状态值()的代码。

class App extends Component {
state = { clickCounts: {} };
onClick = e => {
e.persist();
const clickCounts = { ...this.state.clickCounts };
let clickCount = +clickCounts[e.target.name] || 0;
clickCounts[e.target.name] = ++clickCount;
this.setState({ clickCounts };
console.log(
`Button Name (◀️ outside) = ${e.target.name}`,
this.state.clickCounts
);
};
render() {
const buttons = [1, 2, 3].map(id => (
<button
key={id}
name={`button${id}`}
onClick={this.onClick}
>{`Button #${id}`}</button>
));
return <div className="App">{buttons}</div>;
}
}
class App extends Component {
state = { clickCounts: {} };
onClick = e => {
e.persist();
const clickCounts = { ...this.state.clickCounts };
let clickCount = +clickCounts[e.target.name] || 0;
clickCounts[e.target.name] = ++clickCount;
this.setState({ clickCounts };
console.log(
`Button Name (◀️ outside) = ${e.target.name}`,
this.state.clickCounts
);
};
render() {
const buttons = [1, 2, 3].map(id => (
<button
key={id}
name={`button${id}`}
onClick={this.onClick}
>{`Button #${id}`}</button>
));
return <div className="App">{buttons}</div>;
}
}

让我们看看逻辑错误。

console.log即使在之后进行调用,也无法访问更新的状态值setState

😒 解决方法(不推荐)

作为setState一个操作,您只需等待 React 设置该值即可。

您可能需要等待一段时间才能使用访问更新的状态
setTimeout

onClick = e => {
e.persist();
const clickCounts = { ...this.state.clickCounts };
let clickCount = +clickCounts[e.target.name] || 0;
clickCounts[e.target.name] = ++clickCount;
this.setState({ clickCounts };
setTimeout(() => {
console.log(
`Button Name (⏳ setTimeout) = ${e.target.name}`,
this.state.clickCounts
);
}, 100);
};
onClick = e => {
e.persist();
const clickCounts = { ...this.state.clickCounts };
let clickCount = +clickCounts[e.target.name] || 0;
clickCounts[e.target.name] = ++clickCount;
this.setState({ clickCounts };
setTimeout(() => {
console.log(
`Button Name (⏳ setTimeout) = ${e.target.name}`,
this.state.clickCounts
);
}, 100);
};

太棒了🎉。它有效吧?

是的,但是不是,此时,您只是在祈祷🙏)setState在访问内部状态之前完成setTimeout

此外,您还需要持久化事件以便能够访问事件参数,如第 2 行所示(e.persist())。

请参阅e.persist 的事件池。

😄 推荐方法

React 官方文档中提到了两种方法。

  1. 使用传递给的回调setState
  2. 使用componentDidUpdate生命周期方法

让我们来仔细讨论一下这两个问题。

1. 使用传递给setState

setState具有以下签名

setState(updater[, callback])
setState(updater[, callback])

状态使用方法更新后将调用回调,updater因此回调可以访问更新的内容this.state

这是更新的代码和演示。

onClick = e => {
e.persist();
const clickCounts = { ...this.state.clickCounts };
let clickCount = +clickCounts[e.target.name] || 0;
clickCounts[e.target.name] = ++clickCount;
// - From this,
// this.setState({ clickCounts });
// + To this
this.setState({ clickCounts }, () =>
console.log(
`Button Name (▶️️ inside callback) = `,
this.state.clickCounts
)
);
console.log(
`Button Name (◀️ outside callback) = ${e.target.name}`,
this.state.clickCounts
);
};
onClick = e => {
e.persist();
const clickCounts = { ...this.state.clickCounts };
let clickCount = +clickCounts[e.target.name] || 0;
clickCounts[e.target.name] = ++clickCount;
// - From this,
// this.setState({ clickCounts });
// + To this
this.setState({ clickCounts }, () =>
console.log(
`Button Name (▶️️ inside callback) = `,
this.state.clickCounts
)
);
console.log(
`Button Name (◀️ outside callback) = ${e.target.name}`,
this.state.clickCounts
);
};

2. 使用componentDidUpdate生命周期方法

React 文档“通常建议”使用componentDidUpdate

我还没能找到原因,但我的猜测是因为componentDidUpdate可以访问以前的道具和以前的状态(以及在我的演示中在回调之前被调用)。

以下是使用的代码componentDidUpdate

componentDidUpdate(prevProps, prevState) {
console.log(
`this.state.clickCounts(♻️ componentDidUpdate)`,
this.state.clickCounts
);
}
componentDidUpdate(prevProps, prevState) {
console.log(
`this.state.clickCounts(♻️ componentDidUpdate)`,
this.state.clickCounts
);
}

这个演示表明componentDidUpdate

  1. 可以访问更新的状态值。
  2. 在setState的回调方法之前调用。

👋 临别赠言

componentDidUpdate坦白说,我只使用回调来访问更新的值,因为我只是在写这篇博客时才发现推荐的使用方法😝)。

您可以在CodeSandBox上试用该演示

设置后立即访问 React 状态一文首先出现在Sung 的技术博客上。

鏂囩珷鏉ユ簮锛�https://dev.to/dance2die/accessing-react-state-right-after-setting-it-2kc8
PREV
我的播客订阅
NEXT
🚀 Svelte 快速提示:将商店连接到本地存储本地存储,天哪🤩创建商店使用您的商店就是这样!