@KnightForce

React-Redux. Какой путь правильнее: вызов connect на главном файле или на разных, которым нужно пробросить данные?

Точка входа файл App.
Есть два пути:
1) вызывать connect на App, а потом из него пробрасывать нужные данные через props или context.
2) Вызывать connect только на файлах, где нужны данные из store приложения. Но тогда как получить store? Не использовать же несколько <Provider></Provider>.
  • Вопрос задан
  • 859 просмотров
Решения вопроса 2
nevkusniy
@nevkusniy
KRATOR
Собственно оба варианта корректны. Если рассматривать это в плане удобства использования, то второй вариант однозначно выигрывает. Один большой компонент будет разделен на несколько мелких, те еще на несколько, а те - еще. И вам будет проблематично перебрасывать каждый раз в параметры store.

Provider вызывается один раз в корневом компоненте. Далее же вы просто любой из компонентов подключаете к redux store:
import React, {Component} from "react";

import {connect} from "react-redux";
import {bindActionCreators} from "redux";

/* ваш компонент */

class MyComponent extends Component {
	render() {
		console.log(this.props);

		return (<div></div>);
	}
}

const mapStateToProps = (state) => {
	return {
		state
	}
};

const mapDispatchesToProps = (dispatch) => {
	return {
		dispatch,
		// это мы подключаем собственные actions
		actions: bindActionCreators(actions, dispatch),
	}
};

export default connect(mapStateToProps, mapDispatchesToProps)(MyComponent);
Ответ написан
Комментировать
Приложение вы оборачиваете в провайдер: он должен быть только один. Далее - вызываете коннект там, где нужны данные. При этом старайтесь избегать больших "коннектов" которые мапят кучу стейта и экшенов - т.к. это ведет к невероятному количеству ненужных ререндеров и перерасчетов state...

Как пример - список с большим количеством элементов. Самая первая идея - сделать коннект к компоненту списка и передать ему items из state:

const Item = props => (
  <li>{props.data.title}</li>
)

const List = props => (
  <ul>{props.items.map(item => <Item data={item} />}</ul>
)

const ConnectedList = connect(
  state => ({ items: state.someItems })
)(List)


Но что произойдет, если один айтем из store изменится? Правильно - ререндер всего списка. Даже если вы сделаете Item как PureComponent - все равно получится огромный оверхед.

Второй вариант: коннектить список, но передавать туда только массив id элементов Плюс - коннектить каждый элемент, и получать данные из стора по переданному id. При этом хранить в сторе мы будем отдельно все айтемы (в виде хэшмапа itemId -> item) и отдельно массив с id, либо просто используйте reselect, который поможет вам сделать преобразование items => itemsIds избежав ререндеров (в примере я упущу этот момент, для краткости).

const Item = props => (
  <li>{props.data.title}</li>
)

const ConnectedItem = connect(
  (state, props) => ({ data: state.someItems.entities[props.id] })
)(Item)

const List = props => (
  <ul>{props.items.map(id => <ConnectedItem id={id} />}</ul>
)

const ConnectedList = connect(
  state => ({ items: state.someItems.ids })
)(List)


Другими словами - даже 1000 подконекченных к стору компонентов лучше, чем 1 большой коннект (не скажу, что в 100% случаев, но все же).
Подробнее про этот момент почитать можно тут somebody32.github.io/high-performance-redux

PS
И в целом, я заметил, что вы активно изучаете react - поэтому, рекомендую вот этот цикл статей Practical Redux. Там очень много годной информации по react+redux
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы