2016-11-23 43 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 
      }