gpt4 book ai didi

javascript - 在 ReactJS 中,为什么 `setState` 在同步调用时表现不同?

转载 作者:IT王子 更新时间:2023-10-29 03:05:14 24 4
gpt4 key购买 nike

我试图了解我所看到的一些我无法完全解释的有点“神奇”行为的根本原因,并且从阅读 ReactJS 源代码中看不出这一点。

当同步调用 setState 方法以响应输入上的 onChange 事件时,一切都按预期进行。输入的"new"值已经存在,因此 DOM 实际上并未更新。这是非常可取的,因为这意味着光标不会跳到输入框的末尾。

但是,当运行具有完全相同结构但调用 setState 异步 的组件时,输入的"new"值似乎不存在,导致ReactJS 实际触摸 DOM,这会导致光标跳到输入的末尾。

显然,在异步情况下,某些东西正在干预以将输入“重置”回其先前的 value,而在同步情况下它不会这样做。这是什么机制?

同步示例

var synchronouslyUpdatingComponent =
React.createFactory(React.createClass({
getInitialState: function () {
return {value: "Hello"};
},

changeHandler: function (e) {
this.setState({value: e.target.value});
},

render: function () {
var valueToSet = this.state.value;

console.log("Rendering...");
console.log("Setting value:" + valueToSet);
if(this.isMounted()) {
console.log("Current value:" + this.getDOMNode().value);
}

return React.DOM.input({value: valueToSet,
onChange: this.changeHandler});
}
}));

请注意,代码将登录render 方法,打印出实际DOM 节点的当前value

在“Hello”的两个 L 之间键入“X”时,我们会看到以下控制台输出,并且光标停留在预期位置:

Rendering...
Setting value:HelXlo
Current value:HelXlo

异步示例

var asynchronouslyUpdatingComponent =
React.createFactory(React.createClass({
getInitialState: function () {
return {value: "Hello"};
},

changeHandler: function (e) {
var component = this;
var value = e.target.value;
window.setTimeout(function() {
component.setState({value: value});
});
},

render: function () {
var valueToSet = this.state.value;

console.log("Rendering...");
console.log("Setting value:" + valueToSet);
if(this.isMounted()) {
console.log("Current value:" + this.getDOMNode().value);
}

return React.DOM.input({value: valueToSet,
onChange: this.changeHandler});
}
}));

这与上面的完全相同,只是对 setState 的调用是在 setTimeout 回调中。

在这种情况下,在两个 L 之间键入 X 会产生以下控制台输出,并且光标会跳转到输入的末尾:

Rendering...
Setting value:HelXlo
Current value:Hello

这是为什么?

我理解 React 的 Controlled Component 概念,因此忽略用户对 value 的更改是有意义的。但看起来 value 实际上已更改,然后显式重置。

显然,同步调用 setState 可确保它在重置之前生效,而在任何其他时间调用 setState 都发生在 之后 重置,强制重新渲染。

这是事实吗?

JS Bin 示例

http://jsbin.com/sogunutoyi/1/

最佳答案

这是正在发生的事情。

同步

  • 你按X
  • input.value 是'HelXlo'
  • 你调用setState({value: 'HelXlo'})
  • 虚拟dom说输入值应该是'HelXlo'
  • input.value 是 'HelXlo'
    • 没有采取任何行动

异步

  • 你按X
  • input.value 是'HelXlo'
  • 你什么都不做
  • 虚拟 DOM 说输入值应该是 'Hello'
    • react 使 input.value 为“Hello”。

稍后...

  • setState({value: 'HelXlo'})
  • 虚拟 DOM 说输入值应该是 'HelXlo'
    • react 使 input.value 'HelXlo'
    • 浏览器将光标跳到末尾(这是设置 .value 的副作用)

魔术?

是的,这里有一点魔力。 React 调用在事件处理程序之后同步呈现。这是避免闪烁所必需的。

关于javascript - 在 ReactJS 中,为什么 `setState` 在同步调用时表现不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28922275/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com