[英]Element created in constructor not updated when component rerenders
為什么在構造器中創建的<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') );
<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>
我通過在render()
克隆this.select
使其工作,如下所示: {React.cloneElement(this.select, {value: this.state.icecream})}
但是按照我的問題的幾個答案的建議,改為使用this.select
方法可能更好。 我將看到最適合我的實際代碼的東西,而不僅僅是這個愚蠢的例子:)
因為在構造函數中定義this.select
時,第一次選擇中的this.state.icecream
僅被解釋一次。 因此,當您的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()
。
您還可以使用prop ref
來創建對渲染中<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
定義為一個函數。
第一次選擇不起作用,因為在構造函數中僅被渲染一次。 第二個選擇之所以起作用,是因為每次應用狀態更新時都會重新呈現它。
如果有幫助,請不要將JSX元素視為實際HTML元素的“實例”。 將它們視為您希望應用程序相對於您的狀態外觀的一種簡單方法。 如果我的狀態為“ a”,則使用“ a”呈現選擇,如果我的狀態為“ b”,則使用“ b”呈現選擇,依此類推。
頁面上的第一個選擇框僅在一次調用的構造函數中呈現,因此該組件將始終與首次呈現時保持相同。 換句話說,它是靜態的。 每次更新組件時,都會重新渲染第二個選擇框。
為了修復您的代碼,您可以將構造函數中的行更改為函數:
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 />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.