2017-12-22 19 views
2

https://codesandbox.io/s/jvj6o043yvリアクト - Reduxのカウンターを例アクション倍

を発射Iは、接続プロバイダを反応させ、Reduxのの基礎を完全に理解しようとしている、とmapStateToPropsとMapDispatchToPropsは非常に簡単なカウンターの例を使用しています。エクササイズのポイントは、小道具とアクションをカウンターコンポーネントに注入することです。

私が見ている問題は、ボタンのクリックごとに自分のアクションが2回発砲していることです。私はReduxのnoobですので、私はそれがかなり基本的なエラーです(私は願って)確信しています。私はどこに間違っていたのかを知ることができます。前もって感謝します。

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Provider } from 'react-redux'; 
import { connect } from 'react-redux' 
import { createStore, applyMiddleware } from 'redux'; 
import { createLogger } from 'redux-logger'; 


// Reducer 
const counter = (state = 0, action) => { 
    switch (action.type) { 
    case 'INCREMENT': 
     return state + 1; 
    case 'DECREMENT': 
     return state - 1; 
    default: 
     return state; 
    } 
} 

// store setup 
const configureStore =() => { 
    const middlewares = []; 
    if (process.env.NODE_ENV !== 'production') { 
    middlewares.push(createLogger()); 
    } 
    return createStore(
    counter, 
    applyMiddleware(...middlewares) 
); 
}; 
const store = configureStore(); 

// functional component 
let Counter = ({ 
    currCounter, 
    onIncrement, 
    onDecrement 
}) => (
    <div> 
    <h1>{currCounter}</h1> 
    <button onClick={onIncrement}>+</button> 
    <button onClick={onDecrement}>-</button> 
    </div> 
); 

// Connect logic 
const mapStateToProps = (state) => ({ 
    currCounter: state 
}) 
const mapDispatchToProps = { 
    onIncrement:() => 
    store.dispatch({ 
     type: 'INCREMENT' 
    }), 
    onDecrement:() => 
    store.dispatch({ 
     type: 'DECREMENT' 
    }), 
} 
Counter = connect(
    mapStateToProps, 
    mapDispatchToProps 
)(Counter) 

// Entry point 
const render =() => { 
    ReactDOM.render(
    <Provider store={store}> 
     <Counter /> 
    </Provider>, 
    document.getElementById('root') 
); 
}; 

store.subscribe(render); 
render(); 

double action

答えて

4

あなたが重複派遣を取得している理由は、あなたがあなたのmapDispatchToPropsオブジェクト(および二重矢印構文の一見無害な使用を)書いた方法です。

二重矢印構文中括弧なし() => valueのように、function { return value }に変換されます。

したがって、onIncrementは実際には{ store.dispatch(...) }のようなファンクションではなく、実際にはディスパッチコールの戻り値です。この場合、それは単にディスパッチされたアクションです。

私たちは(単なるアクションオブジェクトを返します)このような何かを見てonIncrementを書く場合:

onIncrement:() => { 
    return { 
     type: "INCREMENT" 
    } 
} 

我々はボタンの押下に適切に派遣アクションで終わります。

これは二重発送の原因です。onIncrementは、最初にstore.dispatchを呼び出してから、返されたオブジェクトから別の発送を回しています。

にかかわらず、あなたはかなり単にあなたonIncrement()にブレースを追加することによってこの問題を解決することができます

onIncrement:() => { 
    store.dispatch({ 
     type: 'INCREMENT' 
    }); 
}, 

先に示したようにあなたは、単に、単にアクションオブジェクトを返すことができます。

+0

ありがとうございます!非常に明快で親切で助けになる。 – shaz

1

mapDispatchToProps()すでに行動を派遣しています。 store.dispatch()を追加することは冗長です。

const mapDispatchToProps = { 
    onIncrement:() => { 
    return { 
     type: 'INCREMENT' 
    } 
    }, 
    onDecrement:() => { 
    return { 
     type: 'DECREMENT' 
    } 
    }, 
} 
1

mapDspatchToProps()を使用している場合は、store.dspatch()を既に暗示しているとおりに追加する必要はありません。

const mapDispatchToProps = { 
    onIncrement:() => { 
    return { 
     type: 'INCREMENT' 
    }}, 

    onDecrement:() => { 
    return{ 
     type: 'DECREMENT' 
    }}, 
} 

乾杯

関連する問題