为什么我在构造函数中创建的<select>
在我选择其他风味时未更新?另一个select
以及文本已更新。
class ConstructorComponent extends React.Component {
constructor() {
super();
this.state = {
icecream: 'vanilla',
};
this.select = (
<select
value={this.state.icecream}
onChange={this.onChange}
>
<option value="chocolate">Chocolate</option>
<option value="vanilla">Vanilla</option>
<option value="strawberry">Strawberry</option>
</select>
);
}
onChange = event => {
this.setState({
icecream: event.target.value,
});
};
render() {
return (
<div>
Icecream flavor: {this.state.icecream}
<br />
{this.select}
<br />
<select
value={this.state.icecream}
onChange={this.onChange}
>
<option value="chocolate">Chocolate</option>
<option value="vanilla">Vanilla</option>
<option value="strawberry">Strawberry</option>
</select>
</div>
);
}
}
ReactDOM.render(
<ConstructorComponent />,
document.getElementById('container')
);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
&#13;
我通过在this.select
中克隆render()
就是这样做的:{React.cloneElement(this.select, {value: this.state.icecream})}
但是,正如我的问题的几个答案所建议的那样,使this.select
成为一种方法可能更好。我会看到最适合我的实际代码的内容,而不只是这个愚蠢的例子:)
答案 0 :(得分:2)
因为第一次选择中的this.state.icecream
只被解释一次,所以在构造函数中定义this.select
时。因此,当您的ConstructorComponent
状态发生变化时第二次重新呈现时,您的第一次选择中无需更新。
您需要将this.select
定义为返回<select>
的函数,如下所示:
this.select = () => {
return (
<select
value={this.state.icecream}
onChange={this.onChange}
>
<option value="chocolate">Chocolate</option>
<option value="vanilla">Vanilla</option>
<option value="strawberry">Strawberry</option>
</select>
)
}
并在渲染中调用this.select()
。
您还可以使用道具<select>
创建对渲染中ref
的引用:
render() {
<select
value={this.state.icecream}
onChange={this.onChange}
ref={select => (this.select = select)} // the magic happens here
>
<option value="chocolate">Chocolate</option>
<option value="vanilla">Vanilla</option>
<option value="strawberry">Strawberry</option>
</select>
}
这样做,您不需要将this.select
定义为构造函数中的函数。
答案 1 :(得分:1)
第一个选择不起作用,因为它只在构造函数中渲染一次。第二个选择有效,因为每次应用程序状态更新时它都会重新呈现。
如果有帮助,请不要将JSX元素视为实际HTML元素的“实例”。将它们视为您希望应用程序与您的州相关的简单方式。如果我的状态是“a”,那么我用“a”渲染一个select,如果我的状态是“b”,那么我用“b”渲染一个select,依此类推。
答案 2 :(得分:1)
页面上的第一个选择框仅在只调用一次的构造函数中呈现,因此组件将始终保持与首次呈现时相同。换句话说,它是静态的。每次更新组件时,将重新渲染第二个选择框。
为了修复代码,您可以将构造函数中的行更改为函数:
this.select = () => (
<select
value={this.state.icecream}
onChange={this.onChange}
>
<option value="chocolate">Chocolate</option>
<option value="vanilla">Vanilla</option>
<option value="strawberry">Strawberry</option>
</select>
);
然后更改你的return语句来调用这个函数:
<br />
{this.select()}
<br />