Передача данных в компонент 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" и сгенерируйте случайное число

И фактический компонент работает так:

  1. Он получает первые 5 чисел, переданных в компонент через реквизит.
  2. После монтирования он начинает слушать хранилище и создает setInterval, который вызывает действие emitNumber() диспетчера действий. Интервал должен показывать реактивность на работе, вы можете представить, что есть кнопка, которая будет вызывать emitNumber().
  3. Хранилище наблюдает за тем, как диспетчер действий выдает "EMIT_NUMBER", и выдает число.
  4. Компонент наблюдает за тем, как хранилище выдало число, и обновляет состояние компонента.
  5. Компонент отмечает, что его состояние изменилось и он восстанавливается.

Я полагаю, что проблема в том, что вы используете синтаксис ES6 (именно так и написан пример... обратите внимание на файл Readme). Вам нужно будет использовать транспортер, такой как Babel, или конвертировать ваш method(param => console.log(param)) синтаксис в нормальный JS (то есть, method(function(param) { console.log(param) });).

Другие вопросы по тегам