Начал изучать Redux для использования в связке с React. Я понял что Redux только управляет состояниями, но мне не удается восстановить поток выполнения для простого примера. Помогите пожалуйста разобраться как он работает в духе 1... 2... 3.... Спасибо.
Есть несколько файлов:
app.js:
export default class App extends Component {
render() {
return (
<div>
<BookList />
</div>
);
}
}
Тут все понятно, но вот второй файл использующий Redux вызывает затруднения.
book-list.js:
class BookList extends Component {
renderList() {
return this.props.books.map((book) => {
return (
<li key={book.title} className="list-group-item">{book.title}</li>
);
});
}
render() {
return (
<ul className="list-group clo-sm-4">
{this.renderList()}
</ul>
);
}
}
function mapStateToProps(state) {
return {
books: state.books
};
}
export default connect(mapStateToProps)(BookList);
В особености mapStateToProps и последняя строка импорта.
И есть редюсер:
const rootReducer = combineReducers({
books: BooksReducer
});
export default rootReducer;
И index.js
const createStoreWithMiddleware = applyMiddleware()(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<App />
</Provider>
, document.querySelector('.container'));
И reduser_books.js
export default function() {
return [
{ title : 'Javascript'},
{ title : 'Java'},
{ title : 'C#'},
{ title : 'Goggle Go'},
{ title : 'Python'}
]
}
Как я понял этот код иллюстрирует самый простой пример связки React-Redux. Как его правильно прочесть?
"Магия" начинает с компонента <Provider>. Его основная задача -- пробросить store во все компоненты приложения. Делает он это с помощью React Context. React Context позволяет определить данные доступные дочерним компонентам. Напрямую React Context вы не используете в приложение, но его использует функция connect.
combineReducers - занимается объединением редьюсеров, создавая каждому редьюсеру отдельное место в state. При инициализации редьюсеров они возвращают свое начальное состояние, которое и помещается в общий state приложения. В вашем случае редьюсер всегда возвращает массив книг (что не совсем правильно с точки зрения Redux), поэтому этот массив и будет присвоен как начальное значение для state.books.
Функция connect делает очень много работы. Основные ее задачи:
state для перерисовки компонентаAction Creators в компонент через propsКак это все работает:
в функции mapStateToProps вы определяете, какие данные из общего state вам нужны в данном компоненте. Функция на входе получает общий state приложения, а возвращает выбранные вами отдельные данные, после чего эти данные будут присвоены как this.props в компоненте. По сути эта функция определяет отображения state на ваш компонент. В вашем случаем вы возвращаете из функции {books: state.books}, т.е. вы говорите что хотите чтобы в компоненте this.props.books было равно state.books (а как мы помним state.books получило массив книг из редьюсера при инициализации).
Примерно с помощью такого же отображения функция connect подключает и Action Creators, но у вас их нет.
Также коннект подписывается на изменения state приложения и в случаи его изменения проверяет, изменились ли данные на которые вы подписаны через mapStateToProps и если они изменились, меняет props что по умолчанию вызывает перерисовку компонента в react.
Функция connect работает через Higher-Order Components создавая компонент-обертку поверх вашего компонента (что хорошо видно через React DevTools) и подключается к react context созданный <Provider> для получения store
Поскольку у все нет экшенов и state приложения не меняется, на этом жизненный цикл вашего приложения заканчивается.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости