簡體   English   中英

觸發子組件的重新渲染

[英]Trigger Re-Render of Child component

我是React的新手,我遇到了幾次同樣的問題。 在這種特殊情況下,我正在嘗試在選擇下拉列表中獲取一個選項,以便在更新文本輸入時進行更新。

我有一個父,App,狀態屬性為“directions”,這是一個數組。 它作為屬性傳遞給子GridSelector,后者創建文本字段和下拉列表。 更改文本字段時,函數會觸發更新父狀態。 這反過來導致GridSelector屬性更新。 但是,最初從該GridSelector屬性生成的下拉值不會重新呈現以反映新的屬性值。

我正在試圖找出最有效的方法來做這個和類似的操作。 在過去,我在子組件中設置了一個狀態,但我想我也讀過這個不合適的狀態。

我的工作地點在amaxalaus.bigriverwebdesign.com

這是每個文件的相關代碼:

App.js

class App extends React.Component {
    constructor(props){
      super(props);
      this.state = {
       directions: [],
       dataRouteDirections: '/wp-json/wp/v2/directions',
       currentDirectionsIndex: 0
     }
     this.addImageToGrid = this.addImageToGrid.bind(this);
     this.changeTitle=this.changeTitle.bind(this);
   }


 componentDidMount(){
    fetch(this.state.dataRouteDirections)
        .then(data => data=data.json())
        .then(data => this.setState({directions:data}));

  }

  addImageToGrid(image) {
    this.refs.grid.onAddItem(image);  //passes image add trigger from parent to child
  }

  createNewDirections(){
    var directions= this.state.directions;
    var index = directions.length;
    var lastDirections = directions[directions.length-1];
    var emptyDirections= {"id":0,"acf":{}};
    emptyDirections.acf.grid="[]";
    emptyDirections.acf.layout="[]";
    emptyDirections.title={};
    emptyDirections.title.rendered="New Directions";

    if (lastDirections.id!==0 ) { ///checks if last entry is already blank
      this.setState({
        directions: directions.concat(emptyDirections),  //adds empty directions to end and updates currentdirections
        currentDirectionsIndex: index
      });
    }
  }

  changeTitle(newTitle){
    var currentDirections = this.state.directions[this.state.currentDirectionsIndex];
    currentDirections.title.rendered = newTitle;
  }

  render() {
    var has_loaded;  //has_loaded was added to prevent double rendering during loading of data from WP
    this.state.directions.length > 0 ? has_loaded = 1 : has_loaded = 0;

    if (has_loaded ) {
     /* const currentGrid = this.state.directions;*/
    return (  //dummy frame helpful for preventing redirect on form submit

        <div>

          <div className="fullWidth alignCenter container">
            <GridSelector 
              directions={this.state.directions} 
              currentDirectionsIndex={this.state.currentDirectionsIndex} 
              changeTitle={this.changeTitle}
            />
          </div>
          <Grid ref="grid" 
            currentGrid={this.state.directions[this.state.currentDirectionsIndex]}
          />
          <ImageAdd addImageToGrid={this.addImageToGrid}/>
          <div className="fullWidth alignCenter container">
            <button onClick={this.createNewDirections.bind(this)}> Create New Directions </button>
          </div>

        </div>

      )
    } else {
      return(
        <div></div>
      )
    }
  }
}

GridSelector.js

class GridSelector extends React.Component {    

  constructor(props) {
    super(props);
    var currentDirections = this.props.directions[this.props.currentDirectionsIndex];
    this.state = {
        currentTitle:currentDirections.title.rendered
    }
  }
    createOption(direction) {
        if (direction.title) {
            return(
                <option key={direction.id}>{direction.title.rendered}</option>
            )
        }   else {
            return(
                <option></option>
            )
        }
    }    

    handleChangeEvent(val) {
        this.props.changeTitle(val);  //triggers parent to update state
    }    

    render() {

        return(
            <div>
                <select name='directions_select'>
                    {this.props.directions.map(direction => this.createOption(direction))}              
                </select>    

                <div className="fullWidth" >
                    <input 
                        onChange={(e)=>this.handleChangeEvent(e.target.value)}
                        placeholder={this.state.currentTitle}
                        id="directionsTitle"
                    />
                </div>
            </div>
        )
    }
}

你犯了一個很常見的初學者錯誤。 在React狀態下應該作為不可變對象處理。 你正在直接改變狀態,所以React無法知道改變了什么。 你應該使用this.setState

更改:

  changeTitle(newTitle){
    var currentDirections = this.state.directions[this.state.currentDirectionsIndex];
    currentDirections.title.rendered = newTitle;
  }

對於這樣的事情:

  changeTitle(newTitle){
    this.setState(({directions,currentDirectionsIndex}) => ({
         directions: directions.map((direction,index)=> 
         index===currentDirectionsIndex? ({...direction,title:{rendered:newTitle}}):direction
    })

暫無
暫無

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

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