2016-06-27 56 views
0

我试图用手建立一个反应/流量的应用程序,大致如下: https://scotch.io/tutorials/getting-to-know-flux-the-react-js-architecture反应组件的状态不更新(FLUX APP)

我已经得到了大部分工作,但是当我更新状态的组件不会重新呈现。谁能帮忙?

谢谢。 :)


回购是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; 

constan ts.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; 

回答

0

好的!所以,我遇到了与this绑定的问题,所以我使用了es6箭头功能。我是新来的一些es6,我有什么不会工作。这不是你如何执行箭头的功能,这就是为什么它不工作...

0

除非我失去了在你的代码的东西,你是不是叫setState随时随地更新您的状态,这是在应对更新的状态和力量的惯用方式重新渲染。

你的_onChange方法应该调用setState与新的状态和组件将自动重新渲染。

更多阅读这里:

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

+0

嗨:) 在这里呼吁replaceState: '(newState)=> this.replaceState;' ,但即使你改变对setState它仍然不起作用。 – user1775718

+0

我只是编辑,以避免混淆... – user1775718

0

所以它好像你调用一个匿名函数,当你实际上可以叫它您_onChange方法中使用this的括号内的setState。

尝试修改此

(newState) => this.setState;

这样:

this.setState(newState);

编辑:

您可能必须包含在你的显示器的构造像这样绑定到这一点:

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