javascript - 简单的 Redux 计数器组件实现

标签 javascript reactjs redux react-redux

我正在尝试使用简单的 Redux 实现一个计数器组件,使用 createStore 创建了 store 并使用了 store.dispatch

完整代码:

/*==================================================
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. 您需要订阅状态更改,这很重要,因为您的组件不知道新状态
  2. stateObject , 你必须从 counter 返回Object ,在您的示例中,您返回 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>
       	<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>

注意:对于React , Redux ( react-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>

关于javascript - 简单的 Redux 计数器组件实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40768308/

相关文章:

javascript:通过函数执行jquery代码变量

javascript - 如何在多页面网站(非 SPA)中使用 react.js?

javascript - 处理标准化响应的最佳方法是什么?

javascript - 更新reducer中的数组项

reactjs - 如何同步Redux和Relay?

javascript - Microsoft Teams Adal 静默身份验证失败(iframe 沙箱)

javascript - 添加但不覆盖文本

javascript - 无法让 lastIndexOf 工作

reactjs - “npm run build”经常卡住我的整个服务器

reactjs - 如何在 React + TypeScript 中设置 Prop 类型