簡體   English   中英

更改狀態后React不重新呈現,我如何設置子組件的狀態?

[英]React not re-rendering after a change in state, how do I setState of child components?

問題:

我有一個立法者集合放入一個表格,字段標題是按鈕,並附加了點擊事件,通過單擊字段按鈕對集合進行排序。

render() {
    const legislatorList = this.populateList() //  creates an Array of Legislator components
    return (
      <div className="legislators">
        <h2>Legislators</h2>
        <table className="table table-bordered">
        <thead>
          <tr>
            <th><button type="button" onClick={ () => this.handleChange("first_name")}  >First</button></th>
            <th><button type="button" onClick={ () => this.handleChange("last_name")}  >Last</button></th>
            <th><button type="button" onClick={ () => this.handleChange("state")}  >State</button></th>
            <th><button type="button" onClick={ () => this.handleChange("party")}  >Party</button></th>
          </tr>
        </thead>
          <tbody>
            { legislatorList }
          </tbody>
        </table>
      </div>
    );

click事件將this.state.legislators重新分配給sort函數的輸出。

handleChange( value ) {
    this.setState( { legislators: this.sort_by( value) })
  }

但即使state.legislators的更新狀態正確排序,該表仍保持不變。

我認為我的問題是立法者的兒童立法者組成部分沒有更新其州。 所以我的問題是你如何更新子組件的狀態?

在任何排序之前: 在此輸入圖像描述

按名字排序后: 在此輸入圖像描述

立法者的其他職能:

sort_by(sort_by) {
  const sorted = this.state.legislators.sort(function(a, b) {
    a_val = a[sort_by]
    b_val = b[sort_by]
    if (a_val < b_val) {
      return -1;
    }
    if (a_val > b_val) {
      return 1;
    }
    return 0;
  });
  return sorted
}

renderLegislator(legislator) {
  return <Legislator legislator={ legislator}/>
}

populateList() {
  return this.state.legislators.map((legislator) =>
    this.renderLegislator(legislator)
  )}
}

這是立法者組成部分:

class Legislator extends React.Component {
  constructor(props) {
    super();
    this.state = {
      legislator: props.legislator,
      fields: ["first_name", "last_name", "state", "party"]
    }
  }

  render() {
    const legislatorRow = this.state.fields.map((field) =>
        <LegislatorField value={ this.state.legislator[field] } />
    )
    return (
      <tr key={this.state.legislator.id}>
        { legislatorRow }      
      </tr>
    );
  }
}

您的子組件中的state.legislator未更新,因為代碼:

this.state = {
  legislator: props.legislator,
  fields: ["first_name", "last_name", "state", "party"]
}

只運行一次,因為構造函數也只運行一次。 並且子組件中的state.legislator不會自動更新,除非您在子組件內顯式執行this.setState()

但是,沒有必要以這樣的方式做。 在子組件中維護自己的props狀態絕對是多余的。

您可以直接在子組件中的render方法中使用this.props ,當父組件中的state發生更改時,子組件將使用新的props重新呈現。

 class Legislator extends React.Component {
  constructor(props) {
    super();
    this.state = {
      fields: ["first_name", "last_name", "state", "party"]
    }
  }

  render() {
    const legislatorRow = this.state.fields.map((field) =>
        <LegislatorField value={ this.props.legislator[field] } />
    )
    return (
      <tr key={this.state.legislator.id}>
        { legislatorRow }      
      </tr>
    );
  }
}

作為獎勵,如果你的this.state.fields總是不變的 - 你不打算稍后更新它,你也不this.state.fields它作為狀態。 您可以簡單地將其設為類實例字段,如this.fields = ["first_name", "last_name", "state", "party"]

主要問題是Array.prototype.sort改變了數組並返回它,而不是返回一個新的數組。

 a = [4,1,2,3];
 b = a.sort();
 a === b // true , they are the same object

因此,當你在handleChange “改變狀態”時,你實際上是在改變分配相同對象引用的狀態,這使得React難以告訴你已經做了任何改變。

最簡單的方法是使用Immutable來存儲立法者的集合。 使用Immutable.List.sort您將擁有一個帶有新值的新數組,而不是舊數組的變異。

另一種方法是通過在狀態上具有sortBy屬性來更清楚地定義組件,該屬性包含用於對列表進行排序的鍵,並更新而不是整個集合。

constructor

this.state = {
  legislator: props.legislator,
  fields: ["first_name", "last_name", "state", "party"],
  sortBy: 'first_name'
}

handleChange

handleChange( value ) {
  this.setState( { sortBy: value })
}

populateList

populateList() {
  return this.state.legislators.map((legislator) =>
    this.renderLegislator(legislator)
  ).sort(function(a, b) {
     a_val = a[this.state.sortBy]
     b_val = b[this.state.sortBy]
     if (a_val < b_val) {
       return -1;
     }
     if (a_val > b_val) {
       return 1;
     }
     return 0;
   });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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