2017-02-08 38 views
3

私は初心者です。孫の状態をどのように扱うべきかを理解するのに苦労しています(孫の状態を持つことは良い考えかどうか見てください)。React JS:孫の状態を設定する方法

私の質問は

1.それはthis.setState((prevState))経由で孫を変更することは可能です...ですか?

2.州として悪い考えを持っていますか?

ここでは、コンポーネントのコンストラクタを示します。

constructor(props) { 
super(props); 
this.state = { 
    input: { 
    example: "", 
    }, 
    invalid:{ 
    example: false 
    }, 
}; 
this.handleChange = this.handleChange.bind(this); 
this.submit = this.submit.bind(this); 
} 

私は孫と子としてthis.state.invalidを見て、this.state.invalid.example

ここにJSXがあります。

<div className="input"> 
    <input type="text" value={this.state.input.example || ''} onChange={this.handleChange} /> 
    { this.state.invalid.example ? <span> This input is invalid </span> : null } 
</div> 
//Here are similar input fields... 

<button onClick={this.submit} type="button">Submit</button> 

onClick={this.submit}が発射されたとき、私は機能、「this.submit」で入力を検証したいと思います。この例では

submit(){ 
for (var key in this.state.input) { 
    if(!this.state.input[key]){ 
    this.setState((prevState, key) => ({ 
     invalid[key]:true, //This causes an error, saying that "SyntaxError: Unexpected token, expected ," 
    })); 
    } 
} 

this.state.invalid.example(すなわち変更)を設定することになっているが、上記のコードは動作しません。

多分、このアプリを分解して<div className="input">を単一のコンポーネントにすることをお勧めします。そうする前に、孫をこのように設定することができるかどうかを明確にしたいと思います。

私はReactJSを勉強している私の周りの誰も知らないので、アドバイスをいただければ幸いです!

+1

可能な複製:http://stackoverflow.com/questions/18933985/this-setstate-isnt-merging-states-as-i-would-expect – forrert

+0

正確には私が探していたものではありません...しかしこれは非常に有益な共有してくれてありがとう! – Hiroki

答えて

3

祖先コンポーネントの状態を状態別に子孫コンポーネントに渡すことはできません。あなたは小道具でそれをすることができますが、小道具を多くのレベル下に通すことにつながります。 contextにも可能性がありますが、それでも良いことではありません。

最も良い方法は、フラックスまたはレフィックスのいずれかを使用することです。私はreduxを好むと、あなたは、あなたのオブジェクトが1つのストアから必要とする変数をconnectメソッドを使って得ることができます。

https://github.com/reactjs/react-redux/blob/master/docs/api.md

もチェックthese videos

+0

この遅刻の返事には申し訳ありません。私は多くのことを試しましたが、今はReduxが私のプロジェクトに最適なソリューションだと感じています。ありがとう! – Hiroki

2

私はそれ自体がコンポーネントの状態を入れ子になったのは悪い考えではないと思います。しかし覚え

in the react documentationを参照してくださいsetState

は、現在の状態にnextStateの浅いマージを実行することが重要です。

あなたの状態が

{ 
    input: { 
    example: "asd", 
    other: "123" 
    }, 
    invalid: { 
    example: false, 
    other: false 
    } 
} 

であり、あなたがsetState({invalid: {example: true}})を呼び出すのであれば、その結果の状態は

{ 
    input: { 
    example: "asd", 
    other: "123" 
    }, 
    invalid: { 
    example: true 
    } 
} 

ようになり、オブジェクトながら、invalid下のすべてが新しい状態に置き換えたに注意してくださいinputの下にそのまま残した(すなわち、浅いマージを行った)。あなたのsubmit機能で

、私はループ全体invalidオブジェクトを作成し、このようsetStateを呼び出します。setState({invalid: invalid})

最後のコードセグメントのエラーは単なる構文エラーです。次のようなオブジェクトを作成することはできません:{invalid[key]:true}、それは{invalid: {[key]: true}}です。

+0

ありがとうございます。たぶん '{invalid:{example:true}}'は動作しますが、 'this.setState((prevState、key))でこの構文を使用すると動作しませんでした。どうやら、 'key'はフィールド名として扱われます(つまり' invalid:{key:true} ') – Hiroki

+0

また、最初の引数として関数を使って' setState'を呼び出すことに気付きました。どこから取得したのかは分かりませんが、 'setState'は最初の引数としてオブジェクトを期待しています。これは現在の状態に浅くマージされます(つまり、トップレベルのプロパティは上書きされます)。 – forrert

0

あなたはこれをしたい場合は、それを行うための方法は次のとおりです。

constructor() { 
    this.state = { 
     input: { 
      example: "", 
     }, 
     invalid:{ 
      example: false 
     }, 
    }; 
} 

assignChildState(state) { 
    var state = Object.assign({}, this.state); 
    state.input = Object.assign({}, state.input); 
    state.input.example = "New Value"; 
    this.setState(state); 
} 

あなたはもちろん、それを処理する関数を作成のようなものでした:

function assignChildState(path, value) { 
    var pieces = path.split("."); 
    var state = Object.assign({}, this.state); 
    var current = state; 
    for (var i = 0; i < pieces.length - 1; i++) { 
     var piece = pieces[i]; 
     console.log(current, piece); 
     if (current[piece].toString() === "[object Object]") { 
      current[piece] = Object.assign({}, current[piece]); 
     } else if (typeof current[piece] === "object" /* array */) { 
      current[piece] = current[piece].concat(); 
     } 
     current = current[piece]; 
    } 
    current[pieces[i]] = value; 
    this.setState(state); 
} 

そして、あなたができますdo:

this.assignChildState("input.example", true); 

これは子の状態を適切に更新します。

すべてのことが、私は間違いなくreduxまたは流束、または私の個人的に好きなflummoxを調べるだろう。

関連する問題