У меня проблема с Flux, которая меня убила. Я вызываю действие при загрузке страницы, но по какой-то причине он не обновляет состояние в компоненте. В этом примере у меня есть this.props.count
, установленный в 5 (по умолчанию в TestStore). Затем я вызываю действие, чтобы увеличить его в componentDidmount
до 6, но он не обновляет состояние компонента. Он остается на 5. Затем, если я нажму ссылку, чтобы вручную обновить его, он будет от 5 до 7.Flux action не обновляет состояние, я делаю это неправильно?
Я думаю, что это как-то связано с тем, что Flux changeListener добавляется к компоненту верхнего уровня после того, как действие посланы?
Если я установил changeListener в componentWillMount
вместо componentDidMount
в компонент верхнего уровня, тогда все будет работать. Но это не похоже на правильный путь? Я чувствую, что что-то упускаю.
Вот console.log и компоненты ...
< тестер />
import React from 'react';
import TestActions from '../actions/TestActions';
export default class Tester extends React.Component {
componentDidMount() {
// this.props.count defaults to 5
// This brings it to 6
TestActions.increaseCount();
}
render() {
return (
<div>
// Count should display 6, but shows 5
Count: {this.props.count}
<br />
<a href="#" onClick={this._handleClick}>Increase</a>
</div>
);
}
_handleClick(e) {
e.preventDefault();
TestActions.increaseCount();
}
}
< Применение />
import React from 'react';
import {RouteHandler} from 'react-router';
import TestStore from '../stores/TestStore';
export default class Application extends React.Component {
constructor() {
super();
this._onChange = this._onChange.bind(this);
this.state = this.getStateFromStores();
}
getStateFromStores() {
return {
count: TestStore.getCount()
};
}
componentDidMount() {
TestStore.addChangeListener(this._onChange);
}
_onChange() {
this.setState(this.getStateFromStores());
}
componentWillUnmount() {
TestStore.removeChangeListener(this._onChange);
}
render() {
return (
<RouteHandler {...this.state} {...this.props}/>
);
}
}
TestStore
var AppDispatcher = require('../dispatchers/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var TestConstants = require('../constants/TestConstants');
var assign = require('object-assign');
var CHANGE_EVENT = 'change';
var _count = 5;
function increaseCount() {
_count = _count + 1;
}
var TestStore = assign({}, EventEmitter.prototype, {
getCount: function() {
return _count;
},
emitChange: function() {
console.log('TestStore.emitChange');
this.emit(CHANGE_EVENT);
},
addChangeListener: function(callback) {
console.log('TestStore.addChangeListener');
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function(callback) {
this.removeListener(CHANGE_EVENT, callback);
}
});
AppDispatcher.register(function(action) {
var text;
switch(action.actionType) {
case TestConstants.INCREASE_COUNT:
increaseCount();
TestStore.emitChange();
break;
default:
// no op
}
});
module.exports = TestStore;
я вижу. Я увидел, что это устранило проблему, когда я изменил ее на 'componentWillMount'. Но я не знал, было ли это решение или нет. Просто потому, что каждый учебник, который я прочитал, имел changeListeners в 'componentDidMount' ... Я не знал, была ли причина для этого или нет :) Я думал, возможно, был способ запустить действие после того, как все родительские компоненты установлен. – TylerW
Ну, может быть, более правильно использовать componentDidMount. В вашем случае я бы реорганизовал архитектуру, имея верхний компонент, выполняющий действия, и дочерний компонент, используя обратные вызовы отцу. – gcedo
Не возражаете ли вы дать небольшой пример? Я немного newb :) – TylerW