簡體   English   中英

重新構造組件時,不會更新在構造函數中創建的元素

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM