Javascript 通过KEFIRJ将数据传递给反应组件

Javascript 通过KEFIRJ将数据传递给反应组件,javascript,reactjs,reactive-programming,kefir.js,Javascript,Reactjs,Reactive Programming,Kefir.js,我是ReactJS和“反应式编程”的新手。我试图根据项目创建一个调度程序、操作和存储,但我不知道如何将数据传递给组件 例如,它不起作用 var data = [1, 2, 3, 4, 5]; var AppDispatcher = Kefir.emitter(); function DataActions() { this.getAllData = function () { AppDispatcher.emit({ actionType: "

我是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'));
var数据=[1,2,3,4,5];
var AppDispatcher=Kefir.emitter();
函数DataActions(){
this.getAllData=函数(){
AppDispatcher.emit({
actionType:“获取所有”
});
};
}
var Actions=新的DataActions();
var getAllDataActionsStream=AppDispatcher.filter(函数(操作){
return action.actionType==“获取全部”;
}).map(功能(操作){
返回函数(数据){
返回数据;
};
});
var dataStream=Kefir.merge([getAllDataActionsStream]).scan(函数(prevData,modificationFunc){
返回修改函数(prevData);
}, {});
var Content=React.createClass({
getInitialState:函数(){
this.onDataChange=this.onDataChange.bind(this);
返回{componentData:[]};
},
componentDidMount:function(){
dataStream.onValue(this.onDataChange);
},
componentWillMount:function(){
dataStream.offValue(this.onDataChange);
log(Actions.getAllData());
},
onDataChange(新数据){
this.setState({componentData:newData});
},
render:function(){
console.log(this.state);
var list=this.state.componentData.map(函数(项,i){
返回(
  • {item}
  • ); }); 返回
      {list}
    ; } }); React.render(,document.getElementById('container');
    我认为问题在于您使用的是ES6语法(这就是示例所用的语法……请注意)。您需要使用类似transpiler的工具,或者将您的
    方法(param=>console.log(param))
    语法转换为正常的JS(即,
    方法(function(param){console.log(param)};
    )。

    在开始详细回答之前,我想先回答这部分:

    但我不知道如何将数据传递给组件

    在您链接的示例中,作者使用React将TODO中的消息传递到主组件中,而不是使用action。因此,这也是我在示例中采用的方法

    var数据=[1,2,3,4,5];
    //现在将在控制台中以前缀“Kefer:”记录AppDispatcher的所有事件
    var AppDispatcher=Kefir.emitter().log(“Kefir:”);
    函数DataActions(){
    //我们的应用程序发出一个随机数。
    this.emitNumber=函数(){
    AppDispatcher.emit({
    actionType:“发射编号”
    })
    };
    }
    var Actions=新的DataActions();
    var emitNumberActionStream=AppDispatcher
    .过滤器(功能(操作){
    return action.actionType==“EMIT_NUMBER”;
    })
    .map(功能(操作){
    log(“发出编号动作!!”;
    返回Math.floor(Math.random()*(10))+1;
    });
    //只有一个流,现在不需要合并。
    //var dataStream=Kefir.merge([getAllDataActionsStream]);
    var Content=React.createClass({
    getInitialState:函数(){
    //使用通过道具传递到此组件的数据设置初始组件数据
    返回{componentData:this.props.data};
    },
    componentDidMount:function(){
    //在每个发出的值上运行this.onDataChange函数
    emitNumberActionStream.onValue(this.onDataChange);
    //每秒使用我们前面创建的操作发出一个数字
    setInterval(函数(){
    Actions.emitNumber();
    }, 1000);
    },
    onDataChange:函数(emittedNumber){
    console.log('更改时的状态:',this.state);
    //通过将发出的编号附加到当前状态的componentData来更新状态
    this.setState({componentData:this.state.componentData.concat([emittedNumber]));
    console.log('updated state:',this.state);
    console.log('--------------');
    },
    render:function(){
    log('RENDER reach!');
    var list=this.state.componentData.map(函数(项,i){
    返回(
    
  • {item}
  • ); }); 返回
      {list}
    ; } }) ; //使用props'data={data}'传入初始数据 React.render(,document.getElementById('container');
    我修改了您给出的不起作用的示例,使其起作用,并且更有意义(希望如此)

    操作和存储的工作方式如下:

    行动:

    • 请求发出一个数字
    商店

    • 监听“发射号码”动作并发射一个随机号码
    实际组件的运行方式如下所示:

  • 它通过道具将最初的5个数字传递到组件中
  • 装载后,它开始侦听存储,并创建一个setInterval来调用操作调度器的emitNumber()操作。时间间隔是为了显示工作时的反应性,你可以想象有一个按钮要按下,它会调用emitNumber()
  • 存储观察动作调度器发出的“emit_NUMBER”并发出一个数字
  • 组件观察存储发出的数字并更新组件的状态
  • 组件观察到其状态已更改,并重新加载

  • 对不起,我没有发布传输版本。请看我编辑的帖子。你能通过调试器或控制台日志检查数据是否在从actions到Kefir或从Kefir到组件的过程中丢失吗?@Moezalz他们是从actions到Kefir丢失的。”AppDispatcher'不发出该操作。谢谢你的回答
    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'));