2017-04-26 4 views
5

ReduxとのリアクションはモデリングUIの状態が優れていますが、が発生する場合があります。が発生する場合があります。UIは個別の手順でそのイベントを処理する必要があり、その一時的なイベント任意の期間にわたって存続する状態の一部として。 JSビン状コードエディタアプリケーションからReact/Reduxで過渡事象をモデル化する方法は?

二つの例、:

  • ユーザがGitHubのの要旨にそのコードをエクスポートします。エクスポートが完了したら、要点を表示する新しいブラウザウィンドウを開きます。したがって、Reactコンポーネント階層は要点のIDを知る必要がありますが、その時点ではウィンドウを開き、要点のエクスポートを完全に気にしなくなります。
  • ユーザがエラーメッセージをクリックすると、エラーが発生した行がエディタによってフォーカスされてエディタに表示されます。繰り返しますが、UIはある時点でどのラインをフォーカスする必要があるかを気にしています。その時点で、(非リアクションベースの)エディタにラインをフォーカスするように指示され、全体が忘れられます。

私が作ってみた少なくとも不満足な解決策がある:

  • トリガイベントが発生すると、(集中する主旨のID、ライン)必要な情報をReduxの状態を更新するためにアクションを派遣
  • その情報に興味のあるReactコンポーネントは、ライフサイクルフックの適切な小道具(componentWillReceivePropsなど)を監視します。
  • コンポーネントは直ちに、「これを処理しました」という基本的に別のイベントをReduxストアにディスパッチします。このイベントは、 。一時イベントデータはRedux状態から削除されます。

このような状況に適したパターンがありますか?私は、おそらく画像の基本的な部分は、アクションに対するUIのレスポンスが常にReactコンポーネント構造から外れることです(新しいウィンドウを開き、エディタのAPIでメソッドを呼び出すなど)。

+0

あなたのやり方は、通常、私がそれをやる方法であり、あなたがReduxを使うとき、これが "働く"方法と信じています。あなたは "this with"フラグを持ち上げ、更新フックで処理します。私は興味深い答えのために、この質問に従います。 –

答えて

1

あなたのソリューションは確かに動作しますしかし、あなたが持ち出すこれらの種類の問題は、全く還元して扱うことに特に適しているとは言えません。単純なReactを使用して、必要な機能をコンポーネントに渡すだけで、私にとってもっと自然な音になります。

たとえば、ある状態を更新するアクションをディスパッチして新しいウィンドウを開くようにするのではなく、そのアクションをディスパッチする代わりに新しいウィンドウを開くだけでは、ウィンドウを開くトリガーアクションをディスパッチするのに必要な情報があれば、同じ場所でウィンドウを開くだけでよいはずです。

エラーメッセージをクリックすると、リアクションではない必須のAPIを呼び出すような例では、エラーメッセージの最も近い親と関数のエディタを渡します。親は、エディタの周りのラッパーへの参照を保持することもできます。たとえそれが深い複数のレベルであっても、あなたがpass down a function to set the refであれば、あなたが望むものを参照するのはそれほど悪くはありません。したがって、親からエラーメッセージコンポーネントに渡された関数は、エディタに保持されているrefのメソッドを単に呼び出すことができます。基本的には次のようなものがあります。

class Parent extends Component { 
    constructor(...args) { 
     super(...args) 

     this.onErrorMessageClick = this.onErrorMessageClick.bind(this) 
    } 

    onErrorMessageClick(lineNumber) { 
     if (this.editor) { 
      this.editor.focusOnLine(lineNumber) 
     } 
    } 

    render() { 
     return (
      <div> 
       <ErrorMessage onClick={ this.onErrorMessageClick } lineNumber={ 1 } /> 
       <ErrorMessage onClick={ this.onErrorMessageClick } lineNumber={ 2 } /> 
       <EditorWrapper editorRef={ (editor) => { this.editor = editor } } /> 
      </div> 
     ) 
    } 
} 

const ErrorMessage = ({ onClick, lineNumber }) => (
    <button onClick={() => onClick(lineNumber) }> 
     { `Error Message For ${lineNumber}` } 
    </button> 
) 

// Just adding EditorWrapper because your editor and error messages probably aren't right next to each other 
const EditorWrapper = ({ editorRef }) => <Editor ref={ editorRef } /> 

class Editor extends Component { 
    focusOnLine(lineNumber) { 
     // Tell editor to focus on the lineNumber 
    } 

    render() { 
     ... 
    } 
} 
1

これらのイベントには、よくredux-thunkを使用します。

本質的に、それは正常なサンクを設定することと変わらず、私はそれにアクションをディスパッチしません。

const openGist = (id) =>() => { 
    // code to open gist for `id` 
} 

このアクションクリエイターは、他のコンポーネントと同様に使用します(例: mapDispatchToPropsにマッピングされ、onClickハンドラで呼び出されます。

私はよく尋ねられる質問は、このコードをコンポーネント自体に直接入れないでください。答えは簡単です。テスト容易性です。副作用の原因となるイベントがなく、副作用の原因となるコードを他のものと分離してテストする方が簡単な場合は、コンポーネントをテストする方がはるかに簡単です。

もう1つの利点は、UXデザイナーがいつか入り込んで、このようなイベントのいくつかについてユーザに何らかのフィードバックを欲しいということです(例えば、エラー行を簡単に強調表示するなど)。この時点でイベントへのアクションは非常に簡単です。

関連する問題