Односторонний поток данных
Поток данных в одностороннем направлении устраняет множество состояний и имеет дело только с одним, который обычно находится внутри хранилища. Чтобы достичь этого, наш объект Store нуждается в логике, которая позволяет нам подписаться на изменения:
var Store = {
_handlers: [],
_flag: '',
onChange: function (handler) {
this._handlers.push(handler);
},
set: function (value) {
this._flag = value;
this._handlers.forEach(handler => handler())
},
get: function () {
return this._flag;
}
};
Затем мы подключим наш основной компонент приложения, и мы будем повторно его отображать каждый раз, когда Store изменит его значение:
class App extends React.Component {
constructor(props) {
super(props);
Store.onChange(this.forceUpdate.bind(this));
}
render() {
return (
<div>
<Switcher
value={ Store.get() }
onChange={ Store.set.bind(Store) }/>
</div>
);
}
}
Обратите внимание, что мы используем forceUpdate, который не рекомендуется. Обычно для обеспечения повторной рендеринга используется компонент высокого порядка(HOC). Мы использовали forceUpdate, чтобы просто привести пример. Из-за этого изменения Switcher становится очень простым. Нам не нужно внутреннее состояние:
class Switcher extends React.Component {
constructor(props) {
super(props);
this._onButtonClick = e => {
this.props.onChange(!this.props.value);
}
}
render() {
return (
<button onClick={ this._onButtonClick }>
{ this.props.value ? 'lights on' : 'lights off' }
</button>
);
}
}
Преимущество этого шаблона заключается в том, что наши компоненты становятся фиктивным представлением данных хранилища. Очень легко думать о компонентах React как о представлении (рендерерах). Мы пишем наше приложение декларативно и разбираемся со сложностью только в одном месте.