简体   繁体   中英

react component not render new data from redux store

I am using react and redux, i want to update my counter value in react view, i am able to console latest state of my redux store but it is not reflect in my react view.

const counter = (state = 0, action) => {
  console.log(action);
  if(action.type == "INCREMENT")
    return state + 1;
  if(action.type == "DECREMENT")
    return state - 1;
  else 
    return state; // return same state if action not identified  
}

const {createStore} = Redux;

const store = createStore(counter);

class Counter extends React.Component {
  constructor() {
    super();
  }

  render() {
    return (
      <div>
      <div>{this.props.state.getState()}</div>
      <button onClick={this.props.onIncrement} >INC</button>
      <button onClick={this.props.onDecrement} >DEC</button>
      </div>
    );
  }
}


const render = () => {
  ReactDOM.render(
    <Counter 
    state={store} 
    onIncrement={
      () => store.dispatch({ type : "INCREMENT" })
    }
    onDecrement={
      () => store.dispatch({ type : "DECREMENT" })
    }
  />,
  document.querySelector('#counter'));
}

store.subscribe(function() {
  console.log(store.getState())
});

render();

Demo

React doesn't automatically re-render the view every time some Javascript data changes, even if your view is bound to that data.

A React component only re-renders in a few cases:

  1. You call this.setState({ ... }) inside the component
  2. A parent React component is re-rendered

There are a few other ways to force a re-render, but they are not recommended because they are much slower and will make your app sluggish.

To correct your sample, do your data binding for actual data on the state object, rather than props . This way React knows to re-render just your component when the counter changes. This might not be very important in a small sample, but this is very important when you want to reuse your component or embed it in a larger page.

Then subscribe to your store, and in the callback invoke setState with any changes. That way React can decide when your re-render should actually happen.

class Counter extends React.Component {
  constructor(props) {
    super();
    this.state = {counter: 0}; // Setup initial state
    this.storeUpdated = this.storeUpdated.bind(this);
    props.store.subscribe(this.storeUpdated); // Subscribe to changes in the store
  }

  storeUpdated() {
    this.setState( // This triggers a re-render
      {counter: this.props.store.getState()});
  }

  render() {
    return (
      <div>
      <div>{this.state.counter}</div>
      <button onClick={this.props.onIncrement} >INC</button>
      <button onClick={this.props.onDecrement} >DEC</button>
      </div>
    );
  }
}

After you've played with this for a while and gotten familiar with how Redux and React work, I suggest you check out this library:

This handles the bridge between React and Redux in a much more clean way than you can achieve by manually doing all the bindings yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM