使用 kefirjs 将数据传递给 React 组件
Pass data to React component with kefirjs
我是 ReactJS 的新手 "reactive programming"。我尝试根据this项目创建一个dispatcher、action和store,但我不知道如何将数据传递给组件。
在 this 示例中它不起作用。
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'));
我认为问题是您使用的是 ES6 语法(这是示例的编写...注意 Readme). You'll need to either use a transpiler like Babel 或将您的 method(param => console.log(param))
语法转换为普通 JS(即, method(function(param) { console.log(param) });
).
在我开始详细回答之前,我想先回答这部分:
but I don't know how to pass data to component.
在示例中,您使用 React 的 props 将作者传递的待办事项链接到主要组件,而不是通过操作。这也是我在示例中采用的方法。
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'));
我修改了你给出的那个不起作用的例子,让它起作用并且更有意义(希望如此)。
Actions 和 Stores 是这样工作的:
操作:
- 请求发出一个数字
店铺
- 监听 "EMIT_NUMBER" 动作并发出一个随机数
而实际的组件是这样运行的:
- 它通过 props 获取传入组件的前 5 个数字。
- 安装后,它开始侦听存储并创建调用动作调度程序的 emitNumber() 动作的 setInterval。间隔是为了显示工作中的反应性,你可以想象有一个按钮可以按下,它会调用 emitNumber()。
- 商店观察动作调度程序发出 "EMIT_NUMBER" 并发出一个数字。
- 组件观察存储发出的数字并更新组件的状态。
- 组件观察到其状态已更改并重新呈现。
我是 ReactJS 的新手 "reactive programming"。我尝试根据this项目创建一个dispatcher、action和store,但我不知道如何将数据传递给组件。
在 this 示例中它不起作用。
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'));
我认为问题是您使用的是 ES6 语法(这是示例的编写...注意 Readme). You'll need to either use a transpiler like Babel 或将您的 method(param => console.log(param))
语法转换为普通 JS(即, method(function(param) { console.log(param) });
).
在我开始详细回答之前,我想先回答这部分:
but I don't know how to pass data to component.
在示例中,您使用 React 的 props 将作者传递的待办事项链接到主要组件,而不是通过操作。这也是我在示例中采用的方法。
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'));
我修改了你给出的那个不起作用的例子,让它起作用并且更有意义(希望如此)。
Actions 和 Stores 是这样工作的:
操作:
- 请求发出一个数字
店铺
- 监听 "EMIT_NUMBER" 动作并发出一个随机数
而实际的组件是这样运行的:
- 它通过 props 获取传入组件的前 5 个数字。
- 安装后,它开始侦听存储并创建调用动作调度程序的 emitNumber() 动作的 setInterval。间隔是为了显示工作中的反应性,你可以想象有一个按钮可以按下,它会调用 emitNumber()。
- 商店观察动作调度程序发出 "EMIT_NUMBER" 并发出一个数字。
- 组件观察存储发出的数字并更新组件的状态。
- 组件观察到其状态已更改并重新呈现。