2017-08-10 17 views
1

このpostを見ましたが、私の場合はどのように適用するのか分かりません。基本的に私は3-4の入力レンジバーを持っています、ユーザーが任意のスライダを変更した場合、他の2/3スライダは自動的に変更されます。バックエンドから取得している初期値。その後私は自分の状態に初期値を追加しました。そのために私はこの他のコンポーネントによる状態変更にDOMを再レンダリングする方法

ここで私の親コンポーネント

constructor(props){ 
     super(props); 
     this.state ={ 
      objectiveData:[] 
     } 
     var {objectiveData} = this.state; 
     this.props.objective_value.map((data,index) =>{ 

      var newObj ={}; 
      newObj['url'] = data.url; 
      newObj['name'] = data.name; 
      newObj['value'] = data.value; 
      newObj['pk'] = data.pk; 
      objectiveData[index] = newObj; 
     }) 
     console.log("lcal",objectiveData) 
     this.setState({objectiveData}); 
} 
updateValue = (obj) =>{ 
     var {objectiveData} = this.state; 
     var selectedData = objectiveData.filter((data) => data.pk === obj.pk); 

     var diff=obj.value - selectedData[0].value; 

     var otherData = objectiveData.filter((data) => data.pk !== obj.pk); 

     var sum = otherData.map((data) =>(data.value)).reduce((a,b) => a + b,0); 
     console.log("sum",sum); 
     if(diff > 0){ 
      for(var i=0;i < objectiveData.length;i++){ 
       if(objectiveData[i].pk !== obj.pk){ 
        console.log("object before value",objectiveData[i].value) 
        objectiveData[i].value = objectiveData[i].value - (objectiveData[i].value/sum); 
        console.log("object after value",objectiveData[i].value) 
       }else{ 
        objectiveData[i].value = obj.value; 
       } 
      } 
     }else if(diff <0){ 
      for(var i=0;i < objectiveData.length;i++){ 
       if(objectiveData[i].pk !== obj.pk){ 
        console.log("object before value plus",objectiveData[i].value) 
        objectiveData[i].value = objectiveData[i].value + (objectiveData[i].value/sum); 
        console.log("object before value minus",objectiveData[i].value) 
       }else{ 
        objectiveData[i].value = obj.value; 
       } 
      } 
     } 
     return this.setState({objectiveData}); 
} 

<MyInputRange maxValue={1} minValue={0} step={0.01} 
       updateProgramObjectiveValue={(value) => this.props.updateProgramObjectiveValue(value)} 
       value={data.value} objective_name={data.objective_name} 
      value_type={data.value_type} url={data.url} pk={data.pk} 
      updateValueLocally={this.updateValue.bind(this)}/> 

は私の子コンポーネント

updateObjectiveValues = (value) =>{ 
this.props.updateValueLocally({"value":value,"pk":this.props.pk}) 
    } 

    render(){ 

     return(
      <InputRange 
        maxValue={this.props.maxValue} 
        minValue={this.props.minValue} 
        step={this.props.step} 
        value={this.state.value} 
        onChange={this.updateObjectiveValues.bind(this)} 

        /> 
     ) 
    } 

あるしかし、私のスライダーを任意の場所でも、スライダーのユーザーmoves.soをしてください動いていないようなコードを書かれています私のコンポーネントを再レンダリングする方法を教えてください。基本的には、setState呼び出しが実行されるたびに反応する必要があります。私はここで腐っているのですか? EDIT 1: クリスの答えに基づいて、私はこの方法

this.setState({objectiveData}); 
     this.forceUpdate(); 

しかし、私は何が不足していないluck..amのように追加しましたか?

+0

あなたはrenderメソッドに親コンポーネントの状態を使用していますか?私はそれが使用されて表示されません。 –

答えて

0

通常、このタイプの質問は、コンポーネント間の統一された状態を固めるためにReduxのようなツールが存在するためです。コンポーネント内のDOMだけでなく、コンポーネント自体もすべて状態の変化に反応します。それをやるのに手間がかかりません...自分でカスタムイベントを設定し、イベントに反応するために他のコンポーネントがリスニングしなければならないイベントを起動する必要があります。作成とイベントがチェックアウトトリガーするための

... https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events

また、同様forceUpdateを使用してアップデートするコンポーネントを強制することができます。デフォルトでは

component.forceUpdate(callback) 

、コンポーネントの状態や小道具が変化し、あなたの コンポーネントが再レンダリングされます。あなたのrender()メソッドがいくつかの 他のデータに依存する場合は、コンポーネントがforceUpdate()を呼び出してRe-rendering を再レンダリングする必要があることをReactに伝えることができます。

forceUpdate()を呼び出すと、shouldComponentUpdate()をスキップして コンポーネントでrender()が呼び出されます。これにより、各子の shouldComponentUpdate()メソッドを含む子コンポーネントの通常のライフサイクルメソッド がトリガーされます。 Reactは、マークアップが変更された場合にのみ、 DOMを更新します。

通常、forceUpdate()のすべての使用を避けるようにし、だけをthis.propsおよびthis.stateからrender()で読み取るようにしてください。

https://facebook.github.io/react/docs/react-component.html#forceupdate

+0

あなたは私の場合のやり方を教えていただけますか? – LowCool

+0

it dint work。私の質問を一度更新してください – LowCool

関連する問題