Reactjs, как изменить состояние компонента из другого компонента
У меня есть компонент реакции, который можно назвать компонентом 1
define([..., /path/component_2.jsx], function(..., Component2) {
var Component1 = React.createClass({
getInitialState: function() {
return {.......};
},
componentDidMount: function() {
.......
dates = ....;
Component2.setState({dates: dates});
}
render: function() { return (<div ...></div>) }
});
}
Как вы можете видеть, я вызываю Component2.setState в этом компоненте. Но я получаю ошибку, как setState не является функцией. Я пробовал это с определением настраиваемой функции вместо функции setState в компоненте 2 и вызова этой функции из компонента 1, но я получаю ту же ошибку, "не является функцией".
И компонент 2:
define([..., ], function(...) {
var Component2 = React.createClass({
getInitialState: function() {
return {.......};
},
render: function() { return (<div ...></div>) }
});
}
Итак, я предполагаю, что в responsejs мы называем компонент только для рендеринга (React DOM elements)? и не может изменить состояние компонента?
Если да, то как я могу изменить состояние компонента из другого компонента, который не является потомком или родителем?
Ответы
Ответ 1
Компоненты не публично раскрывают свое состояние. Также важно помнить, что состояние ограничено экземпляром компонентов, а не их определением.
Чтобы взаимодействовать между компонентами, вы можете запустить собственную службу подписки на события.
var events = new EventEmitter();
// inside Component1
events.emit('change-state', newState);
// inside Component2
events.on('change-state', function(state) {
this.setState(state);
});
Однако это быстро станет трудно управлять.
Более разумным решением является использование Flux. Он позволяет вам явно управлять состоянием всего вашего приложения и подписаться на изменения в разных битах состояния в ваших компонентах. Стоит попробовать обернуть вокруг себя голову.
Компонент, который хочет общаться, должен отправить действие, и это действие будет нести ответственность за изменение чего-либо в магазинах, ваш другой компонент должен подписаться на это хранилище и может обновить его состояние на основе изменения.
Ответ 2
Вы можете использовать общее состояние между двумя компонентами.
Вы можете создать "mixin", подобный этому
app.mixins.DateMixin = {
getInitialState: function ()
return {
dates: []
}
}
};
а затем в ваших компонентах вы можете включить эти микшины, используя массив mixins
define([..., /path/component_2.jsx], function(..., Component2) {
var Component1 = React.createClass({
mixins: [app.mixins.DateMixin],
getInitialState: function() {
return {.......};
},
componentDidMount: function() {
.......
dates = ....;
this.setState({dates: dates});
}
render: function() { return (<div ...></div>) }
});
}
define([..., ], function(...) {
mixins: [app.mixins.DateMixin],
var Component2 = React.createClass({
getInitialState: function() {
return {.......};
},
render: function() { return (<div ...></div>) }
});
}
Теперь ваши компоненты разделяют состояние "даты", и вы можете изменить/проверить его в обоих из них.
NB: вы также можете совместно использовать методы таким же образом, записывая компонент mixin.
Изменить: предлагаю вам посетить этот сайт http://simblestudios.com/blog/development/react-mixins-by-example.html