2017-01-21 2 views
1

推奨:問題は、(Reduxのような及び他のフラックス実装)ReactJSとして

https://facebook.github.io/react/docs/thinking-in-react.html#step-3-identify-the-minimal-but-complete-representation-of-ui-state

我々は、(他の状態から計算することができる状態を維持should'tそれを派生データと呼びます)、それ以外の場合は状態を設定するときに別のデータを設定する必要があります。

しかし、以下の例を考えてみます。私のページで2つの状態

  1. 交通光の色があります

    緑/赤=光

  2. は今後どんな人がいます道路の向こう側:人=真(人がいる)/ (人なし)

私たちが知っているように、交通信号が赤色のときに人々は道路を渡ることはできません。

だから、私たちは3つの正常な組み合わせ状態を持っている:

  1. 光=緑と人=真
  2. =緑と人=光
  3. 光=赤と人々偽=偽

その他の状態ライト=赤と人=真は無効です。赤= 光我々は、この場合には、人=偽を計算することができ

の得られたデータです。しかし、光=緑の場合できません。

問題は、私は値を設定すると、私はそれ以外の場合は、無効な状態につながる可能性があり、人々に値を設定する必要があります。

この問題を解決するにはどうすればよいですか?私の状態をデザインするには?

これらの管理に役立つライブラリはありますか?まず私の状態間の依存関係を定義することができます。ライブラリは、それらの一貫性に対する応答です。他の人と競合する状態値を設定すると、他の人は正しい値に変更されます。

私は欲しいものを示すための簡単な例を書いていますが、このようなライブラリはありますか?、someNewColorが赤の場合

this.setState({ 
    light: someNewColor, 
    people: someNewColor === red ? false : this.state.people 
}); 

class ComplexState { 
    constructor(config, initialState){ 
     this.config = config; 
     this.state = initialState; 

     this._checkAll(); 
    } 

    setState(key, value){ 
     var config = this.config[key]; 
     if(config && config.type === ComplexState.Types.Enum){ 
      //Set Enum data type 
      if(Array.isArray(config.definitionField) && config.definitionField.indexOf(value) !== -1 || 
       config.definitionField[value] && typeof config.definitionField[value].checker === 'function' && config.definitionField[value].checker(this.state)){ 
       //Set the value 
       this.state[key] = value; 
       //If there is a conflict, modify other values 
       Object.keys(this.state).forEach(_key => { 
        if(key === _key){//Self 
         return; 
        } 
        var _value = this.state[_key]; 
        var _config = this.config[_key]; 
        if(!Array.isArray(_config.definitionField) && _config.definitionField[_value] && typeof _config.definitionField[_value].checker === 'function' && !_config.definitionField[_value].checker(this.state)){ 
         //Conflict, adapt to correct value 
         this.state[_key] = _config.definitionField[_value].adapter(this.state); 
        } 
       }) 

       //Check for conflicts 
       this._checkAll(); 
      }else{ 
       //Invalid value 
      } 
     } 
    } 

    getState(){ 
     return Object.assign({}, this.state); 
    } 

    //Check for conflicts 
    _checkAll(){ 
     Object.keys(this.state).forEach(_key => { 
      var _value = this.state[_key]; 
      var _config = this.config[_key]; 
      if(!Array.isArray(_config.definitionField) && _config.definitionField[_value] && typeof _config.definitionField[_value].checker === 'function' && !_config.definitionField[_value].checker(this.state)){ 
       //Conflict 
       throw new Error('invalid state' + JSON.stringify(this.state)); 
      } 
     }) 
    } 
} 

ComplexState.Types = { 
    Enum : 0 
} 

を使用すると、瀬田値に必要がある場合は、状態の別の部分を設定した場合にのみ、あなたがこのような何かを行うことができ、

var myStates = new ComplexState({ 
    light : { 
     type : ComplexState.Types.Enum, 
     definitionField : ['red', 'green'] 
    }, 
    people : { 
     type : ComplexState.Types.Enum, 
     definitionField : { 
      'false' : null, 
      'true' : { 
       checker : function(state){ 
        return state.light !== 'red'; 
       }, 
       adapter : function(state){ 
        if(state.light === 'red'){ 
         return 'false'; 
        } 
        return state.people; 
       } 
      } 
     } 
    } 
}, { 
    light : 'Green', 
    people : 'false' 
}) 
console.log(myStates.getState());//{light: "Green", people: "false"} 
myStates.setState('people', 'true'); 
console.log(myStates.getState());//{light: "Green", people: "true"} 

//when I set light value to red, the people value is automatically set to false 
myStates.setState('light', 'red'); 
console.log(myStates.getState());//{light: "red", people: "false"} 
+0

真が緑と赤が偽であるブールに光を変えるとこれを解決する必要があります。あなたが常に(光と人)を評価するならば、唯一真の価値は、光が緑色で人がいることです。 – Chase

+0

私は、あなたが私の言うことを誤解していると思います。評価(軽い&人)は意味がなく、表現ではありません。彼らは私のページのちょうど2つの州であり、独立して設定することができます。 &を削除するために私の説明を編集しました。 – junhan

+0

私は理解しますが、あなたがしているのは「交差点に人がいますか?」です。あなたがしたいのは、それぞれの値を独立して正しく設定できることです。 「交差点に人がいる?」とは、常に(光と人)によって評価できる派生データです。それぞれがあなたのアプリでこれらの2つの値を独立して変更できるように、それぞれを保護します。必要な2つの状態値は、式(ライト&&人)から「交差点に人がいる」ことを常に導き出す限り、ライトと人々だけです。 – Chase

答えて

0

を、それを使用します人々は自動的に偽に設定されます。それ以外の場合は、以前に設定した値のままです。

編集:あなたは、このクリーナーを作りたい場合は

、あなたが人々と光が完全に独立して行う必要があります。例:

this.setState({ 
    light: someNewColor 
}) 

光だけの人を計算することができないため、現在のところ動作しません。

+0

これは私が避けたいものです.2つの状態を保持するのと同じです:配列とその長さ。 'this.setState({ list:listOfArray、 length:listOfArray.length }); 矛盾した状態が発生し、ページにエラーが発生する可能性があります。 – junhan

+0

問題は、それが完全に独立していないということです。それは独立した部分を持っています(光が緑の場合)が、光に依存しています(赤の場合)。光に基づいて人を計算する方法はないので、両方を保つ必要があります。この設定では、回避する方法はありません。あなたの配列の例では、長さは配列に完全に依存するため、両方を必要としません。 –

+0

私はそれらを管理するための図書館を探したい。まず私の状態間の依存関係を定義することができます。図書館は私の州の一貫性に対する応答です。他の人と競合する状態値を設定すると、他の人は正しい値に変更されます。私は理論的に実装することが可能だと思います。 – junhan

関連する問題