为什么我的应用程序状态未更新(redux)

时间:2018-02-10 03:21:45

标签: javascript reactjs redux

我正在关注官方文档中的redux counter教程,但我的应用程序状态似乎没有更新。更清楚的是,本质上应用程序是一个带有增量按钮和减量按钮的计数器,它在屏幕上显示当前值。

我可以通过控制台记录值,因为它会改变,但它不会在屏幕上输出它。任何人都可以告诉我我做错了什么

import React, { Component } from 'react';
import { createStore } from 'redux';


const counter = (state = 0, action) => {
  switch(action.type) {
    case 'INCREMENT':
      return state + 1;
    case 'DECREMENT':
      return state -1;
    default:
      return state;
  }
}
const store = createStore(counter);
store.subscribe(()=>{
  console.log(store.getState());
});
class App extends Component {
  render() {
    return (
      <div className="App">
        <h1>Counter Application</h1>
        <hr/>

        <Counter 
          value={store.getState()}
          onIncrement={() => store.dispatch({type: 'INCREMENT'})} 
          onDecrement={() => store.dispatch({type: 'DECREMENT'})} 
        />
      </div>
    );
  }
}


const Counter = ({
  value, 
  onIncrement,
  onDecrement
}) => {
  return(
    <div>
      <h1>{value}</h1>
      <button onClick={onIncrement}> Plus </button>
      <button onClick={onDecrement}> Minus </button>
    </div>
  )
}


export default App;

3 个答案:

答案 0 :(得分:0)

您需要提供商并连接react-redux

中的组件

答案 1 :(得分:0)

您的App组件不会重新呈现。

AFAIK,只是因为只有在组件的状态或道具发生变化时才能触发重新渲染。

您需要在商店订阅中触发您的App组件重新渲染。我看到你的商店订阅基本上什么都不做,只记录在这里。

store.subscribe(()=>{
  console.log(store.getState());
});

你可以做这样的事情,每当redux商店更新时触发重新渲染:

const page = document.getElementById('page');
const render = () => ReactDOM.render(<App />, page);
render();
store.subscribe(render);

答案 2 :(得分:0)

原因:

在您的情况下,组件不知道redux存储中的更改,因此它不会重新呈现。

组件只有在接收到新的道具/上下文时才会重新渲染 或者如果他们的本地状态已更新(通常调用setState()

解决方案1(我认为直接回答你的问题)

const Counter = ({ value, onIncrement, onDecrement }) => {
  return (
    <div>
      <h1>{value}</h1>
      <button onClick={onIncrement}> Plus</button>
      <button onClick={onDecrement}> Minus</button>
    </div>
  )
};


class App extends Component {

  componentDidMount() {
    this._unsub = store.subscribe(this._update);
    this._update();
  }

  componentWillUnmount() {
    this._unsub();
    this._unsub = null;
  };

  state = { value: undefined };

  render() {
    const { value } = this.state;
    return (
      <div className="App">
        <h1>Counter Application</h1>

        <Counter
          value={value}
          onIncrement={this._increment}
          onDecrement={this._decrement}
        />
      </div>
    );
  }

  _decrement = () => store.dispatch({ type: 'DECREMENT' });

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

  _update = () => {
    const value = store.getState();
    this.setState({ value });
  }
}

解决方案2(正确的)

使用react-redux模块

  

同时检查这些:
   - normalizr
   - normalizr + keyWindow concept talk
   - Reselect
   - ComputingDerivedData Post
   - react-reselect-and-redux post

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

import { _valueSelector1, _valueSelector2 } from 'app/feature/selectors';
import { increment, decrement } from 'app/feature/actions';

const mapStateToProps = (state, props) => ({
  valueOne: _valueSelector1(state, props),
  valueTwo: _valueSelector2(state, props),
})

const mapDispatchToProps = {
  increment,
  decrement,
};

@connect(mapStateToProps, mapDispatchToProps)
export class YourComponent extends Component {

  static propTypes = {
    valueOne: PropTypes.number,
    valueTwo: PropTypes.number,
    increment: PropTypes.func.isRequired,
    decrement: PropTypes.func.isRequired,
  }

  render() {
    const { valueOne, valueTwo, increment, decrement } = this.props;
    return (
      <div>
        <span>{valueOne}</span>
        <Counter value={valueTwo} onIncrement={increment} onDecrement={decrement} />
      </div>
    )
  }
}