2016-11-23 159 views
1

我想實現用簡單的終極版計數器組成部分,創造了store使用createStore和使用store.dispatch簡單終極版Counter組件實現

完整代碼:

/*================================================== 
 
This is only to format the code, I have used this editor, 
 
you can scroll down for the fiddle having error. 
 
==================================================*/ 
 

 

 
const createStore = Redux.createStore; 
 

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

 
const store = createStore(counter); 
 

 
let Counter = React.createClass({ 
 
    getInitialState() { 
 
     return store.getState() 
 
    }, 
 

 
    incrementCounter() { 
 
     store.dispatch({ 
 
      type: 'INCREMENT' 
 
     }); 
 
    }, 
 
    decrementCounter() { 
 
     store.dispatch({ 
 
      type: 'DECREMENT' 
 
     }); 
 
    }, 
 

 
    render() { 
 

 
     console.log('NEW STATE:', store.getState(), this.state) 
 
     return (
 
       <div> 
 
       <p>{this.state.counter}</p> 
 
       <div> 
 
       <button onClick={this.incrementCounter}>+</button> 
 
       <button onClick={this.decrementCounter}>-</button> 
 
       </div> 
 
       </div> 
 
    ) 
 
    } 
 

 
}) 
 

 
ReactDOM.render(< Counter/> , document.getElementById('container')) 
 
      
 

DEMO JSFIDDLE

我的問題:我是不是能夠得到在渲染塊更新儲值當我點擊incrementCounterdecrementCounter功能

注:請與我裸露,我是新來的終極版。

回答

1

你有幾個問題

  1. 你需要認購狀態變化,這一點很重要,因爲你的組件不知道新的狀態
  2. stateObject,你必須從返回counterObject,在你的例子中你返回NumberINCREMENTDECREMENT

const createStore = Redux.createStore; 
 

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

 
const store = createStore(counter); 
 

 
let Counter = React.createClass({ 
 
    incrementCounter() { 
 
    store.dispatch({ type: 'INCREMENT' }); 
 
    }, 
 
    
 
    decrementCounter() { 
 
    store.dispatch({ type: 'DECREMENT' }); 
 
    }, 
 

 
    render() { 
 
    return <div> 
 
     <p>{ this.props.value }</p> 
 
     <div> 
 
     <button onClick={this.incrementCounter}>+</button> 
 
     \t <button onClick={this.decrementCounter}>-</button> 
 
     </div> 
 
    </div> 
 
    } 
 
}) 
 

 
const render =() => { 
 
    ReactDOM.render(
 
    // get updated state value, and pass it to component 
 
    <Counter value={ store.getState().counter } />, 
 
    document.getElementById('container') 
 
) 
 
}; 
 

 
store.subscribe(render); 
 
render();
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="container"></div>

注意:爲ReactReduxreact-redux)提供組件調用Provider,你不需要使用store.subscribe,然而在作爲我的例子類似的引擎蓋邏輯

更新:

const { Provider, connect } = ReactRedux; 
 
const { createStore, bindActionCreators } = Redux; 
 

 
// Component 
 
let Counter = ({ value, onIncrement, onDecrement }) => (
 
    <div> 
 
    <p>{ value }</p> 
 
    <div> 
 
     <button onClick={ onIncrement }>+</button> 
 
     <button onClick={ onDecrement }>-</button> 
 
    </div> 
 
    </div> 
 
); 
 

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

 
// actions 
 
const onIncrement =() => { 
 
    return { type: 'INCREMENT' } 
 
} 
 

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

 
// map state and actions 
 
const mapStateToProps = (state) => { 
 
    return { 
 
    value: state.counter 
 
    } 
 
} 
 

 
const mapDispatchToProps = (dispatch) => { 
 
    return bindActionCreators(
 
    { onIncrement, onDecrement }, 
 
    dispatch 
 
); 
 
} 
 

 
Counter = connect(
 
    mapStateToProps, 
 
    mapDispatchToProps 
 
)(Counter); 
 

 
const store = createStore(counter); 
 

 
ReactDOM.render(
 
    <Provider store={ store }> 
 
    <Counter /> 
 
    </Provider>, 
 
    document.getElementById('container') 
 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.4.6/react-redux.js"></script> 
 
<div id="container"></div>

+2

作爲亞歷山大已經在這裏做,你也減速需要使用Object.assign因爲它是返回一個整數(新計數)而不是定義爲初始狀態的狀態對象,例如{counter:1}。 –

+0

@ alexander-t,感謝您的幫助。我真的很感激你是否也可以給我一個'Provider'的例子。請........ –

+0

@RAVI MONE看看我的更新... –

1

你的主要問題是:

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

尤其是這行:

  case 'INCREMENT': 
      return state.counter + 1; 
     case 'DECREMENT': 
      return state.counter - 1; 

什麼要退?一個號碼!但是,你的狀態形狀的物體{counter: Number}

所以,你必須返回一個新的對象是這樣的:

  case 'INCREMENT': 
      return {counter: state.counter + 1} 
     case 'DECREMENT': 
      return {counter: state.counter - 1} 

上述變化應該修復它。 是你的減速機內更靈活,您應該分配新的對象,像這樣的存在狀態:

  case 'INCREMENT': 
      return { 
       ...state, 
       counter: state.counter + 1 
      } 
     case 'DECREMENT': 
      return { 
       ...state, 
       counter: state.counter - 1 
      }