2017-09-22 10 views
0

私はReact.jsの初心者ですが、私は何か新しいことを学びたいと思っています。 2つの階層コンポーネントがあり、親の状態を更新しても子コンポーネントは再レンダリングされません。React.js、onChangeイベントによる子コンポーネントの再レンダリング

親にonChangeイベントを持つ要素があります。変更が発生すると、JSONをRESTから要求し、親の状態を設定します。次に、このメソッドでは、変更された状態で構成されるデータプロパティを持つ子コンポーネントのレンダリングを呼び出しています。そして何も起こらない。それは一度だけ起こっている。次のオプションの選択は何もしません。

もっと経験豊富な人が自分のコードをすばやく見て、どのように実現しなければならないかを説明できますか?

import React, { Component } from 'react'; 
import ReactDOM from "react-dom"; 

import $ from "jquery"; 
import './App.css'; 
import "../node_modules/bootstrap/dist/css/bootstrap.min.css"; 
import cafeList from "./cafeList.json"; 

class App extends Component { 
    render() { 
    return (
     <div className="App container"> 
     <div className="App-header"> 
      <h2>Dining Rooms Menu </h2> 
     </div> 
     <CafeSelect /> 
     </div> 
    ); 
    } 
} 

class CafeSelect extends Component{ 
    constructor(props) { 
    super(props); 
    this.state = { 
     cafeList: cafeList, 
     goods_for_current_cafe: [] 
    }; 
    this.handleChange = this.handleChange.bind(this); 
    } 
    handleChange(){ 
    var self = this; 
    var cur_val_cafe = $('#select-cafe-type').find(":selected").val(); 
    console.log(cur_val_cafe); 
    $.ajax({ 
     url: 'https://example.com/rest', 
     type: 'POST', 
     data: { 
     auth: 'authkey', 
     getcafeguide: 1, 
     idpoint: cur_val_cafe, 
     }, 
    }) 
    .done(function(res) { 
     var data = $.parseJSON(res); 
     self.setState({ 
     goods_for_current_cafe: data 
     }); 

     console.log(self.state); 
     ReactDOM.render(
     <GoodsGroup 
      data={self.state.goods_for_current_cafe} 
     />, 
     document.getElementById("goods-group") 
    ); 
    }) 
    } 

    render() { 
    return(
     <div> 
     <div className="row"> 
      <label className="col-lg-2">Choose dining room</label> 
      <div className="control-wrapper col-lg-10"> 
       <select className="form-control" id="select-cafe-type" onChange={this.handleChange}> 
       {cafeList.map(function(cafe, index){ 
         return <option key={ index } value={cafe.IDPoint}>{cafe.Point}</option>; 
       })} 
       </select> 
      </div> 
      </div> 
     <div id="goods-group"></div> 
     <div id="goods-list"></div> 
     </div> 
    ) 
    } 
} 

class GoodsGroup extends Component{ 
    constructor(props) { 
    super(props); 
    this.handleChange = this.handleChange.bind(this); 
    } 

    handleChange(){ 
    var cur_group_val = $('#select-goods-type').find(":selected").val(); 
    var matches = $.grep(this.props.data, function(e) { return e.GoodsGroup == cur_group_val }); 
    ReactDOM.render(
     <GoodsList 
     data={matches} 
     />, 
     document.getElementById("goods-list") 
    ); 
    } 

    componentWillMount() { 
    console.log(this.props.data); 
    let _ = require('underscore'); 
    var data = this.props.data; 

    let categories = _.keys(_.countBy(data, function(data) { 
     return data.GoodsGroup; 
    })); 
    this.setState({ 
     categories: categories, 
     goods: this.props.data 
    }); 

    } 

    render() { 

    return (
     <div className="row"> 
     <label className="col-lg-2">Choose goods category</label> 
     <div className="control-wrapper col-lg-10"> 
      <select className="form-control" id="select-goods-type" onChange={this.handleChange}> 
      {this.state.categories.map(function(group, index){ 
        return <option key={ index } value={group}>{group}</option>; 
       })} 
      </select> 
     </div> 
     </div> 
    ) 
    } 
} 


export default App; 

答えて

1

これは、この作業を取得するためにMVPの変化です。 、あなたのGoodsGroupコンポーネントで

、以下

prepareData() { 
    console.log(this.props.data); 
    let _ = require('underscore'); 
    var data = this.props.data; 

    return _.keys(_.countBy(data, function(data) { 
     return data.GoodsGroup; 
    })); 
} 

にごcomponentWillMount機能を変更したり、機能がReactDom.renderから撮影

render() { 
    const categories = this.prepareData(); 
    return (
     <div className="row"> 
      <label className="col-lg-2">Choose goods category</label> 
      <div className="control-wrapper col-lg-10"> 
       <select className="form-control" id="select-goods-type" onChange={this.handleChange}> 
        {categories.map(function (group, index) { 
         return <option key={index} value={group}>{group}</option>; 
        })} 
       </select> 
      </div> 
     </div> 
    ) 
} 

説明

に変更する必要がありますレンダリング

React要素が以前にコンテナにレンダリングされていた場合、これは更新を実行し、最新のReact要素を反映するために必要に応じてDOMを変更するだけです。

GoodsGroupコンポーネントはすでにレンダリング時に存在するため、componentWillMount関数は呼び出されません。レンダリング時に常に呼び出されるように変更します。

+0

ああ、ああ、あまりにもありがとう!あなたの最初の時間に直面しているときに新しいことにコーディングでは、いくつかのことは時々ひどく理解することが難しいです。と申し訳ありません4私の悪い英語、ネイティブスピーカーではありません。もう一度ありがとう、あなたは最高です!!! –

1

componentWillMount - ライフサイクルメソッドのみONCEすなわち動作しますマウントが発生し、また、componentWillMount内部の状態変化があなたのシナリオではhttps://facebook.github.io/react/docs/react-component.html#componentwillmount を参照してください。再レンダリングをトリガしないとき、装着はすでに最初の選択時に起こりました。

は、以下を使用してみ

オプション1:レンダリングの下の方法をフェッチshouldComponentUpdateを使用すると、カテゴリを移動()

getCategories() { 
    const data = this.props.data; 
    return _.keys(_.countBy(data, (data) => data.GoodsGroup)) 
} 

shouldComponentUpdate(nextProps) { 
    return !R.equals(this.props, nextProps)// using ramda for comparison 
} 

render() { 
    const categories = this.getCategories() 

return (
    <div className="row"> 
     <label className="col-lg-2">Choose goods category</label> 
     <div className="control-wrapper col-lg-10"> 
      <select className="form-control" id="select-goods-type" onChange={this.handleChange}> 
       {categories.map(function (group, index) { 
        return <option key={index} value={group}>{group}</option>; 
       })} 
      </select> 
     </div> 
    </div> 
) 

オプション2:他に使用componentWillReceiveProps()

getCategories(props) { 
    const data = props.data; 
    return _.keys(_.countBy(data, (data) => data.GoodsGroup)) 
} 

componentWillMount() { 
const categories = this.getCategories(this.props) 
this.setState({ 
    categories: categories, 
    goods: this.props.data 
    }) 
} 

componentWillReceiveProps(nextProps) { 
    const categories = this.getCategories(nextProps) 
    this.setState({ 
    categories: categories, 
    goods: nextProps.data 
    }) 
} 

render() { 

return (
    <div className="row"> 
     <label className="col-lg-2">Choose goods category</label> 
     <div className="control-wrapper col-lg-10"> 
      <select className="form-control" id="select-goods-type" onChange={this.handleChange}> 
       {this.state.categories.map(function (group, index) { 
        return <option key={index} value={group}>{group}</option>; 
       })} 
      </select> 
     </div> 
    </div> 
) 
関連する問題