2016-10-03 9 views
0

は、このコードを犠牲にして反応し、反応しました。es6:スプレッド演算子を使用したresultの値は?

私の質問は、普及したオフェレーターが使用されたときの最終的な結果です。私がそれを正しく理解すれば、基本的に反復可能または配列を個々の引数に変えます。

ですから、出力は...演算子で取得したすべてのフィールドを使用して別のJSONオブジェクトを作成しているだけです。

const INITIAL_STATE = { postsList: {posts: [], error:null, loading: false}, 
         newPost:{post:null, error: null, loading: false}, 
         activePost:{post:null, error:null, loading: false}, 
         deletedPost: {post: null, error:null, loading: false}, 
        }; 

export default function(state = INITIAL_STATE, action) { 
    let error; 
    switch(action.type) { 

    case FETCH_POSTS:// start fetching posts and set loading = true 
    return { ...state, postsList: {posts:[], error: null, loading: true} }; 

ので、これはFETCH_POSTSの結果である:

{ 
postsList: {posts: [], error:null, loading: false}, 
          newPost:{post:null, error: null, loading: false}, 
          activePost:{post:null, error:null, loading: false}, 
          deletedPost: {post: null, error:null, loading: false, }, 

ので、基本的にはpostsListキーが存在していたことを知っているし、それを上書きするのに十分スマートでしたか?

react.jsアプリの状態の有無を確認することに頼るのは、アンチパターンですか?キー値がnullの場合は「このキーが存在するかどうか」を意味します。

なぜ、配列キーを使用してキーの値を変更しますか? INITIAL_STATE ['postsList'] = {... postsObject}

または新しい演算子を使用していますか?

+0

FETCH_POSTSの結果は '{ postsListあろう: 、activePost偽}:{記事:[]、エラー:ヌル、ローディング:真}、 newPost:{ポスト:ヌル、エラー:ヌル、ローディング{戻り値に設定されているので、deletedPost:{投稿:null、エラー:null、読み込み:false、}、 ' '...'は基本的にObject.assign()を置き換えますhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign – erichardson30

+0

@rrosttはReduxの状態を*必須にする必要があります不変であるとみなされる。ここでそれを行う方法については、いくつかの良い文書があります:http://redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html – riscarrott

答えて

0

Object.assignと... spread演算子は、浅いコピーに適しています。ディープコピーでは、lodash/deepCloneやdeepCopy utilを好きです。

export default function deepCopy(obj) { 
    if (typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Array]') { 
    let finalObj = []; 
    for (let i = 0, len = obj.length; i < len; ++i) { 
     finalObj.push(deepCopy(obj[i])); 
    } 
    return finalObj 
    } else if (typeof obj === 'object') { 
    let finalObj = {}; 
    for (let prop in obj) { 
     if (obj.hasOwnProperty(prop)) { 
     finalObj[prop] = deepCopy(obj[prop]); 
     } 
    } 
    return finalObj; 
    } else { 
    return obj; 
    } 
} 

私は盲目的に私の状態を新しい状態に深くコピーします。そして、さまざまなオブジェクトにObject.assignを適用します。したがって、私のコードは:

const newState = deepCopy(state); 
Object.assign(newState.prop1, { innerProp: 'val' }); 
+1

これは、何かを行う*ひどい*方法です。ディープコピーは、古い状態のどのような形の突然変異も防止しますが、変更されていない状態は再使用しません。これは少なくとも3つの理由で悪いことです。 1)それはより多くのメモリを使います2)すべてをコピーするには時間がかかります3)React-Reduxは、トリプルイコールを比較して何かが変わらなかったかどうかを知っています。ディープクローン作成時には、React-Reduxに従ってすべてが変更され、小さな変更ごとにアプリ全体が再レンダリングされます。パフォーマンスの悪夢。 – DDS

+0

@DDS、ご意見ありがとうございます。私が古い状態で配列を変更すると、バグが発生します。したがって、浅いコピーを行い、新しい配列を作成し、変更されていない他のネストされたオブジェクトを残すソリューションはありますか? – vijayst

+0

はい、それはまさに解決策です。配列 '.slice()'だけです。また、変更されたオブジェクトを新しいオブジェクトに置き換えます(突然変異はありません)。変更しないオブジェクトは置き換えないでください。新しい配列またはオブジェクトを作成するときは、変更されないすべての値をコピーし、それらをディープコピーしないでください。残りのスプレッドを使うことは、これらのことを実行する便利な方法です。 – DDS

1

あなたは状態を不変として扱いたいと思います。減速機は、新しい状態オブジェクトを返すべきであり、既存の状態オブジェクトを変更してはならない。 INITIAL_STATE ['postLists'] = somethingNewを実行すると、 INITIAL_STATEによって参照されるオブジェクトを変更しています。

この場合、spread演算子を使用する代わりに、既存のオブジェクトに基づいて新しいオブジェクトを作成し、いくつかのプロパティをオーバーロードするObject.assignを使用します。

言われているように、実際には減速機定義のstateのデフォルト値以外のINITIAL_STATEは使用しないでください。

関連する問題