Html 反应:输入范围滑块未在Chrome中将最后一个值传播给其所有者

Html 反应:输入范围滑块未在Chrome中将最后一个值传播给其所有者,html,google-chrome,reactjs,Html,Google Chrome,Reactjs,以下小提琴使用React 0.13显示3个输入范围作为受控部件。状态更改后,彩色方块将更新以显示新的rgb颜色 在Firefox中,它可以像我期望的那样工作,但在Chrome中却不行。具体而言,彩色方形组件显示倒数第二个值,而滑块显示最近的值 这是一个React/Chrome错误吗?或者我可以修复代码中的某些内容吗 代码: var ColorDisplay=React.createClass({ 道具类型:{ 红色:React.PropTypes.number.isRequired, 绿色:Re

以下小提琴使用React 0.13显示3个输入范围作为受控部件。状态更改后,彩色方块将更新以显示新的rgb颜色

在Firefox中,它可以像我期望的那样工作,但在Chrome中却不行。具体而言,彩色方形组件显示倒数第二个值,而滑块显示最近的值

这是一个React/Chrome错误吗?或者我可以修复代码中的某些内容吗

代码:

var ColorDisplay=React.createClass({
道具类型:{
红色:React.PropTypes.number.isRequired,
绿色:React.PropTypes.number.isRequired,
蓝色:React.PropTypes.number.isRequired
},
_toHex:函数{
var hex=parseInt(s,10).toString(16);
返回十六进制长度==1?“0”+十六进制:十六进制;
},
render:function(){
var rr=这个.\u toHex(这个.props.red),
gg=这个.\u toHex(这个.props.green),
bb=这个.\u toHex(这个.props.blue);
var color=“#”+rr+gg+bb;
var divStyle={backgroundColor:color};
返回(
{color}
);
}
});
var ColorSlider=React.createClass({
道具类型:{
红色:React.PropTypes.number.isRequired,
绿色:React.PropTypes.number.isRequired,
蓝色:React.PropTypes.number.isRequired,
changeHandler:React.PropTypes.func.isRequired
},
getInitialState:函数(){
返回{
瑞德:这个,道具,瑞德,
格林:这个,道具,格林,
蓝色:这个。道具。蓝色
};
},
handleOnChange:函数(名称、事件){
var new_state={};
新状态[名称]=event.target.value;
本.设置状态(新状态);
this.props.changeHandler();
},
handleClick:函数(名称、事件){
var new_state={};
var self=这个;
['red'、'green'、'blue'].forEach(函数(名称){
new_state[name]=React.findDOMNode(self.refs[name]).value;
});
本.设置状态(新状态);
this.props.changeHandler();
},
_getRGB:function(){
返回此.state;
},
_toHex:函数{
var hex=parseInt(s,10).toString(16);
返回十六进制长度==1?“0”+十六进制:十六进制;
},
render:function(){
var red_style={color:'red'};
var grn_style={color:'green'};
var blue_style={color:'blue'};
var min=0;
var max=255;
var阶跃=1;
var rr=这个.\u toHex(这个.state.red),
gg=这个.\u toHex(这个.state.green),
bb=这个.\u toHex(这个.state.blue);
返回(
红色
{this.state.red}/{rr}
绿色
{this.state.green}/{gg}
蓝色
{this.state.blue}/{bb}
设置颜色(将滑块与Chrome上的正方形同步)
);
}
});
var App=React.createClass({
getInitialState:函数(){
返回{红色:0,绿色:0,蓝色:0};
},
更新:函数(){
var rgb=this.refs.slider.\u getRGB();
//值现在是字符串!
这是我的国家({
红色:rgb.red,
绿色:rgb.green,
蓝色:rgb.blue
});
},
render:function(){
返回(
);
}
});
React.render(,document.getElementById('app'));

您的
手柄中有竞态条件,请在
颜色滑块中更改
。在状态更新后,您应该调用
this.props.changeHandler()
,而不是在调用
setState
后直接调用。这是因为
setState
不同步。然而,它之所以能在Firefox中正常工作,是因为这可能是一场非常快速的竞赛,而Firefox恰好站在没有显示错误的一边

要强制它始终工作并消除竞争,请在
colorsslider
中为
handleOnChange
使用类似的内容:

handleOnChange: function(name, event) {
    var new_state = {};
    new_state[name] = event.target.value;
    this.setState(new_state, function() {
        this.props.changeHandler();
    });
}
它会很好的工作。这样做的目的是确保只有在状态实际更新并呈现之后才会调用
this.props.changeHandler
。正是由于这个特殊的原因,
setState
有一个可选的回调

请注意,您不必将
setState
中的回调绑定到
this
,因为React将为您自动绑定它

进一步编辑:

您也只会遇到这个问题,因为您直接从父级调用子组件函数(bad),并且在不需要时直接从DOM读取数据。从组件自身外部调用组件的方法是一个巨大的禁忌。相反,您应该做的是通过onChange回调向上传递新的颜色值,并在父级中以这种方式对其作出反应

例如:

允许您通过将
更新
功能更改为以下内容,在父
应用程序
组件中设置颜色更改:

update: function(name, value) {
  var stateChange = {};
  stateChange[name] = value;
  this.setState(stateChange);
}
“设置状态不同步”和“向上传递新的价值链”…这对我来说是一个重要的教训,谢谢。
handleOnChange: function(name, event) {
  var new_state = {};
  new_state[name] = event.target.value;
  this.setState(new_state, function() {
    this.props.changeHandler(name, this.state[name]);
  })
}
update: function(name, value) {
  var stateChange = {};
  stateChange[name] = value;
  this.setState(stateChange);
}