【问题标题】:react component state not updating (FLUX App)反应组件状态未更新(FLUX App)
【发布时间】:2016-10-28 22:30:52
【问题描述】:

我正在尝试手动构建一个 react/flux 应用程序,大致如下: https://scotch.io/tutorials/getting-to-know-flux-the-react-js-architecture

我已经完成了大部分工作,但是当我更新状态时,组件不会重新渲染。有人可以帮忙吗?

谢谢。 :)


回购是https://github.com/jmsherry/flux_hand

CounterStore.js

import Dispatcher from 'Flux';
import AppDispatcher from './../dispatcher/AppDispatcher';
import CounterConstants from '../constants/constants';
import { EventEmitter } from 'events';
import assign from 'object-assign';


let _count = 5;

function increment() {
  _count +=1;
}

function decrement() {
  _count -=1;
}

let CounterStore = assign({}, EventEmitter.prototype, {

  getCount() {
    return _count;
  },

  emitChange() {
    this.emit(CounterConstants.CHANGE_EVENT);
  },

  /**
   * @param {function} callback
   */
  addChangeListener(callback) {
    this.on(CounterConstants.CHANGE_EVENT, callback);
  },

  /**
   * @param {function} callback
   */
  removeChangeListener(callback) {
    this.removeListener(CounterConstants.CHANGE_EVENT, callback);
  },

  dispatcherIndex: AppDispatcher.register(function(payload) {
    console.log('blah', arguments);
    var action = payload.action;
    var text;

    switch(action.actionType) {
      case CounterConstants.INCREMENT:
          console.log('inc', _count);
          increment();
          console.log(_count);
          CounterStore.emitChange();
        break;

      case CounterConstants.DECREMENT:
      console.log('dec', _count);
        decrement();
        console.log(_count);
        CounterStore.emitChange();
        break;
    }

    return true; // No errors. Needed by promise in Dispatcher.
  })

});

export default CounterStore;

AppDispatcher.js

import { Dispatcher } from 'Flux';

const AppDispatcher = new Dispatcher();

AppDispatcher.handleViewAction = function(action) {
  console.log('in', arguments);
  this.dispatch({
    source: 'VIEW_ACTION',
    action
  });
}

export default AppDispatcher;

constants.js

import keyMirror from 'keymirror';

const CounterConstants = keyMirror({
  INCREMENT: null,
  DECREMENT: null
});

CounterConstants.CHANGE_EVENT = 'change';

export default CounterConstants;

actions.js

import AppDispatcher from '../dispatcher/AppDispatcher';
var CounterConstants = require('../constants/constants');

const CounterActions = {

  /**
   * @param  {string} text
   */
  increment() {
    AppDispatcher.handleViewAction({
      actionType: CounterConstants.INCREMENT
    });
  },

  decrement() {
    AppDispatcher.handleViewAction({
      actionType: TodoConstants.DECREMENT
    });
  }

};

export default CounterActions;

counter.js

import React,{Component} from 'react';
import ReactDOM from 'react-dom';
import CounterConstants from './../constants/constants';
import AppDispatcher from './../Dispatcher/AppDispatcher.js';
import Controls from './Controls';
import Display from './Display';

class Counter extends Component {
  render(){
    return (
      <div className="counter">
        <h1>My counter</h1>
        <Display />
        <Controls />
      </div>
    )
  }
}

export default Counter;

controls.js

import React,{Component} from 'react';
import ReactDOM from 'react-dom';
import CounterConstants from './../constants/constants';
import AppDispatcher from './../dispatcher/AppDispatcher';
import CounterActions from './../actions/actions';

class Controls extends Component {
  render(){
    console.log('here', AppDispatcher);
    return (
      <div className="controls">
        <button onClick={CounterActions.increment}>+</button>
        <button onClick={CounterActions.decrement}>-</button>
      </div>
    )
  }
}

export default Controls;

display.js

import React,{Component} from 'react';
import ReactDOM from 'react-dom';
import CounterConstants from './../constants/constants';
import CounterStore from './../stores/CounterStore';

// Method to retrieve application state from store
function getAppState() {
  console.log('getting app state...');
  return {
    count: CounterStore.getCount()
  };
}

class Display extends Component {
  constructor(props) {
    super(props);
    this.state = getAppState();
  }

  // Update view state when change event is received
  _onChange() {
    console.log('prechange', this.state);
    const newState = getAppState();
    console.log('newState', newState);
    (newState) => this.setState;
  }

  // Listen for changes
  componentDidMount() {
    CounterStore.addChangeListener(this._onChange.bind(this));
  }

  // Unbind change listener
  componentWillUnmount() {
    CounterStore.removeChangeListener(this._onChange.bind(this));
  }

  shouldComponentUpdate( newProps, newState ) {
    console.log('shouldComponentUpdate', arguments);
  }

  render() {
    let count = getAppState().count;
    console.log('rendering', count, this.state);
    return (
      <div className = "display" >
        <p>State: { this.state.count }</p>
        <p>count: { count }</p>
      </div>
    )
  }
}

export default Display;

【问题讨论】:

    标签: reactjs reactjs-flux


    【解决方案1】:

    除非我在您的代码中遗漏了某些内容,否则您不会在任何地方调用 setState 来更新您的状态,这是 React 更新状态并强制重新渲染的惯用方式。

    您的_onChange 方法应该使用新状态调用setState,组件将自动重新渲染。

    更多阅读:

    https://facebook.github.io/react/docs/component-api.html

    【讨论】:

    • 嗨 :) 它在这里调用 replaceState:(newState) =&gt; this.replaceState;,尽管即使您将其更改为 setState 它仍然不起作用。
    【解决方案2】:

    因此,您似乎是在匿名函数的括号中调用 setState,而实际上您可以在 _onChange 方法中使用 this 调用它。

    尝试更改此设置

    (newState) =&gt; this.setState;

    到这里:

    this.setState(newState);

    编辑:

    您可能必须在 Display 构造函数中包含对 this 的绑定,如下所示:

      constructor(props) {
        super(props);
        this.state = getAppState();
        this._onChange = this._onChange.bind(this);
      }
    

    【讨论】:

      【解决方案3】:

      好的!所以,我遇到了this 绑定的问题,所以我使用了 es6 箭头函数。我是 es6 的一些新手,我所拥有的将无法正常工作。这不是你执行箭头函数的方式,这就是它不起作用的原因......

      【讨论】:

        猜你喜欢
        • 2020-04-11
        • 1970-01-01
        • 2019-08-30
        • 2016-01-19
        • 2017-05-05
        • 1970-01-01
        • 1970-01-01
        • 2020-10-14
        • 2021-05-24
        相关资源
        最近更新 更多