2016-03-27 9 views
1

私は世界を還元して新しく、新聞アプリを作ろうとしています。私は現在、ユーザーが特定の新聞のタイトルを検索できる検索機能に取り組んでいます。問題は、私が最初に 'a'とタイプすると、状態は ''です。そして、例えば「b」と入力すると、状態は「ab」でなければならないという用語が「a」であることが示されます。私はこの世界的な状態を確認するためにレフィックスクロムツールを使用しています。Redux/React - 検索フィールドが還元状態を即座に更新していません

マイActioncreatorは、(それだけに渡された用語を返します)本当に簡単です:ここでは

export function search(term) { 
    return{ 
    type:SEARCH, 
    term 
    } 
} 

は減速である:ここでは

const SearchReducer = (state = '', action) => { 

    switch (action.type) { 
     case SEARCH: 
      return action.term; 
     default: 
      return state; 
    } 

} 

は、ルート減速です:

/*Application state*/ 
const rootReducer = combineReducers({ 
    weather: WeatherReducer, 
    filters: FilterReducer, 
    articles:ArticleReducer, 
    search: SearchReducer // this should be 'ab', but is 'a' 
}); 

これは本当に簡単な設定です。ここで私はreduxと通信しています。

私は私の材料-UIテキストフィールド(私もバニラ入力フィールドを試してみました)

<TextField style={style.searchWidget.search} 
      floatingLabelText="Search" 
      value={this.state.term} 
      onChange={this._onSearchChange} 
/> 

とき_onSearchChangeのFUNCが発射されたユーザーが何かを持っています。

_onSearchChange(event) { 
    this.setState({term: event.target.value}); 
    this.props.search(this.state.term); 
} 

これは、この検索コンポーネントの現在の状態を設定します。次に、グローバル状態を更新する検索アクションをディスパッチします。しかし、正しく動作しません。グローバルな状態は常に1ステップ遅れています。

編集: 還元的ではなく反応するようです。コンポーネントの状態が瞬時に更新されていません。正しい期間は、actionreducerに渡され、reduxの失敗ではありません。状態を設定した後、this.state.termを出力しようとしました。状態が更新されていないように見えます。

答えて

1

実際にそれはreduxとは関係ありません。反応しながら作業している間は、反応した状態を更新するとすぐに更新された状態を取得できないことを覚えておく必要があります。例を見てみましょう。私たちは、引数として、状態バージョンとにupdateState関数を呼び出す場合

getInitialState: function() { 
    return { 
    myState: 0 
    } 
}, 

updateState: function(stateVersion) { 
    console.log(this.state.myState); //this will print 0 
    this.setState({ myState: stateVersion }); 
    console.log(this.state.myState); //this will print 0 
} 

は今初めてそれは我々が引数として1または2または任意の番号を送信した場合でも、コンソールの両方に0を出力します。 引数として2を送信したとします。その関数の次の呼び出しでその状態を別の引数で得ることができます。 しかし、これにも反応してください。 私たちがそれを更新するとすぐに状態が更新されない場合、どうすればその状態で作業できるのかと思うかもしれません。しかし、反応が良い少年です... 状態を更新する関数を呼び出し、次に最後に更新された状態で作業するために別の関数を呼び出すと、その関数で作業できます。

私はすでに還元状態が更新されない理由についてあなたの質問に答えていると思います。

もうひとつ考えてみましょう。あなたの検索還元剤に還元状態を使用している場合、なぜ反応状態も扱っています。検索したパラメータを直接アクションに渡すことができます。レデューサーの状態から即座にそのアップデートを入手できます。 これはコードの簡素化に役立ちます。

+0

チップをありがとう。それはうまく動作します:) – onurhb

0

解決策が見つかりました。 React - State not updated 実際には、setStateは状態を即時に設定していないようです。 代わりにコールバック関数を使用しました。

_onSearchChange(event) { 
    this.setState({term: event.target.value}, function() { 
     console.log(this.state.term) 
    }); 
    } 

「a」と入力すると「a」が記録されます!

+0

、私はまだあなたがReduxのを使用しているので、あなたは「派遣アクション」アプローチを利用している確保をお勧めします。しかし、入力を設定するために状態を使用している場合は、新しい小道具が上から降りたときにその変更を上書きできるようにしてください。これはちょっとしたタイプの「楽観的なレンダリング/アップデート」として私を襲っています。したがって、入力を設定するために状態を使用している場合、newPropsがReduxフローから入ったときに、コンポーネントへのローカル状態を更新する方法があることを確認してください。あなたが入力を設定する状態を使用していない場合は – marcacyr

+0

、しかし、あなたは(私は上記の私の答えでいう)SETSTATEでコールバックを使用してから離れるとちょうどReduxの店からの発送を利用することから利益を得ることができます。 今週、私は(ないのSO、中人)ときsetState' '上のコールバック用のオプションを使用する理由/についての質問を擁立しました。コールバックが実際に呼び出されたときにメソッド火災順序を説明する、とした後、私は、言って締結し、「再来の使用は一般的に、あなたの 'setState'呼び出しにコールバックを追加するなどの回避策の必要性を否定します。」 – marcacyr

3

この回答は、Aniket Nandanが指摘したところに少し追加されています。上の小道具に頼るのではなく、あなたのReactコンポーネント内でsetStateを使用しています。

Reduxを使用する主な目的は、状態をアプリケーションと一緒にコンテナに入れることです。これを行う利点は、複数のコンポーネント間で状態を共有できるため、コンポーネントツリー内のコンポーネントに小道具を介して物事を渡すことができることです。

ステートコンテナ(ステートマシンを使用していることを常に思い出させています)を使用すると、ツリーを介してコールバックを渡す必要がなく、アプリケーションを構築できます。上。その代わりに、Reduxは状態の変更を処理し、すべてを「Proact through React」に戻します。そのノートオン

_onSearchChange(event) { 
    this.setState({term: event.target.value}); 
    this.props.search(this.state.term); 
} 

、上記のコードを見て、あなたが用語にSETSTATEなぜあなたのポストから、私は疑問に思ってたが、その後いつも小道具を通じて、あなたが受け取った関数を呼び出しますか?検索はReduxストアからのディスパッチメソッドを呼び出しますか?そうでなければ、あなたは正しく配線されていません。

さらに、connectを正しく使用した場合(react-redux)、Reduxストアからのディスパッチ方法を使用可能にする必要があります(これはコンテキストによって行われます)。

Reduxのは、動作するように設計されている方法は、より多くのこのようなものである:何それから起こることReduxのは、状態の更新を処理すべきである、と新しい状態は(小道具を経由して反応するようにReduxのからこれを流れます

_onSearchChange(event) { 
    this.props.dispatch({ type: 'SEARCH', term: event.target.value }); 
} 

Reduxのフードの下のすべての接続を通して起こります。これはかなり素晴らしいです!)。あなたの減速に基づいて

const SearchReducer = (state = '', action) => { 

    switch (action.type) { 
     case SEARCH: 
      return action.term; 
      break; 
     default: 
      return state; 
    } 

} 

(^^上にコピーされた)とcombineReducersの使用は、あなたが「AB」を入力した場合{ search: { term: 'ab' } }を持っている状態で終わる必要があり、それは「」だけ入力した後でなければなりません'a'、後ろに遅れているよりむしろ。

setStateの使用で実際に起こったことは、最初の状態(私は''と仮定しています)がthis.props.searchに初めて渡されたことでした。一方、「a」と入力した後で、コンポーネントが'a'に更新されました。次に、「b」と入力したときに、状態は「ab」に更新されましたが、this.props.searchsetStateの実行が完了する前の状態からの用語のみを受信して​​いました。

これは実際にはReduxがすばらしい理由の1つです。これは、独自のコンテナ内のユーザーアクションに基づいて状態が適切に更新されるようにするためです。 。

Reduxを使用するためのアドバイスを残しておきます。setStateをReduxを使用するアプリケーションにあるReactコンポーネント内で使用することはめったにありません。状態の部分は、設定したいかどうかにかかっすべきコンポーネント内setStateを使用する際の意思決定にのみ、そのコンポーネント内に存在し、アプリケーションの残りの部分はそれについて知っている必要はありません。私は例を考えることができず、私が提供できるものはおそらくかなり工夫されているでしょう。その点で、私が1つ考えることができない理由は、アプリケーションでこのようなユースケースを持つことはまれではないと思うからです。

だから、あなただけのReduxのストアから発送方法を使用してReduxのは、そのワークフローで状態の更新を処理し、状態がコンポーネントに小道具を通って下方に流れることを可能にすることが可能にこだわるべきです。この流れを遵守すれば、起こり得る問題の「同期が外れている」という奇妙な状態が発生するのを防ぐことができます。このアプローチでは

+0

あなたの時間をありがとう、私は今事をはっきりと見る! – onurhb