Передача данных в компонент React с помощью kefirjs
Я новичок в ReactJS и "реактивное программирование". Я пытался создать диспетчер, действие и хранилище в соответствии с этим проектом, но я не знаю, как передать данные в компонент.
В этом примере это не работает.
var data = [1, 2, 3, 4, 5];
var AppDispatcher = Kefir.emitter();
function DataActions() {
this.getAllData = function () {
AppDispatcher.emit({
actionType: "GET_ALL"
});
};
}
var Actions = new DataActions();
var getAllDataActionsStream = AppDispatcher.filter(function (action) {
return action.actionType === "GET_ALL";
}).map(function (action) {
return function (data) {
return data;
};
});
var dataStream = Kefir.merge([getAllDataActionsStream]).scan(function (prevData, modificationFunc) {
return modificationFunc(prevData);
}, {});
var Content = React.createClass({
getInitialState: function() {
this.onDataChange = this.onDataChange.bind(this);
return {componentData: []};
},
componentDidMount: function() {
dataStream.onValue(this.onDataChange);
},
componentWillMount: function(){
dataStream.offValue(this.onDataChange);
console.log(Actions.getAllData());
},
onDataChange(newData) {
this.setState({componentData: newData});
},
render: function() {
console.log(this.state);
var list = this.state.componentData.map(function (item, i) {
return (
<li key={i}>{item}</li>
);
});
return <ul>{list}</ul>;
}
});
React.render(<Content />, document.getElementById('container'));
2 ответа
Прежде чем я начну отвечать подробно, я хочу ответить на эту часть заранее:
но я не знаю, как передать данные компоненту.
В приведенном вами примере автор передает Todos в основной компонент, используя реквизит React, а не действие. Вот такой подход я использую и в своем примере.
Теперь вот мой пример. Я настоятельно рекомендую посмотреть на пример и прочитать то, что я написал ниже.
var data = [ 1, 2, 3, 4, 5 ];
// This will now log all events of the AppDispatcher in the console with the prefix 'Kefer: '
var AppDispatcher = Kefir.emitter().log("Kefir: ");
function DataActions() {
// Our application has an action of emitting a random number.
this.emitNumber = function() {
AppDispatcher.emit({
actionType: "EMIT_NUMBER"
})
};
}
var Actions = new DataActions();
var emitNumberActionStream = AppDispatcher
.filter(function(action) {
return action.actionType === "EMIT_NUMBER";
})
.map(function(action) {
console.log("EMIT_NUMBER ACTION OCCURRED!!");
return Math.floor(Math.random() * (10)) + 1;
});
// Only one stream, no need to merge right now.
//var dataStream = Kefir.merge([ getAllDataActionsStream ]);
var Content = React.createClass({
getInitialState: function() {
// Set initial componentData using the data passed into this component's via props
return { componentData: this.props.data };
},
componentDidMount: function() {
// On each emitted value run the this.onDataChange function
emitNumberActionStream.onValue(this.onDataChange);
// Every second emit a number using the Actions we created earlier
setInterval(function() {
Actions.emitNumber();
}, 1000);
},
onDataChange: function(emittedNumber) {
console.log('state on change:', this.state);
// Update the state by appending the emitted number to the current state's componentData
this.setState({ componentData: this.state.componentData.concat([emittedNumber])});
console.log('updated state: ', this.state);
console.log('-----------------');
},
render: function() {
console.log('RENDER AGAIN!');
var list = this.state.componentData.map(function(item, i) {
return (
<li key={i}>{item}</li>
);
});
return <ul>{list}</ul>;
}
})
;
// Pass in initial data using props 'data={data}'
React.render(<Content data={data}/>, document.getElementById('container'));
Я изменил приведенный вами пример, который не работал, чтобы он работал и имел немного больше смысла (надеюсь).
Действия и магазины работают так:
Действия:
- Запрос номер будет выпущен
магазины
- Прослушайте действия "EMIT_NUMBER" и сгенерируйте случайное число
И фактический компонент работает так:
- Он получает первые 5 чисел, переданных в компонент через реквизит.
- После монтирования он начинает слушать хранилище и создает setInterval, который вызывает действие emitNumber() диспетчера действий. Интервал должен показывать реактивность на работе, вы можете представить, что есть кнопка, которая будет вызывать emitNumber().
- Хранилище наблюдает за тем, как диспетчер действий выдает "EMIT_NUMBER", и выдает число.
- Компонент наблюдает за тем, как хранилище выдало число, и обновляет состояние компонента.
- Компонент отмечает, что его состояние изменилось и он восстанавливается.
Я полагаю, что проблема в том, что вы используете синтаксис ES6 (именно так и написан пример... обратите внимание на файл Readme). Вам нужно будет использовать транспортер, такой как Babel, или конвертировать ваш method(param => console.log(param))
синтаксис в нормальный JS (то есть, method(function(param) { console.log(param) });
).