Обычно я создаю свои компоненты, используя следующий шаблон:
import selectors from '../store/selectors'
import someAction1 from '../actions/someAction1'
import someAction2 from '../actions/someAction2'
import someAction3 from '../actions/someAction3'
class MyComponent extends React.Component {
render() => {
return <Fragment>
<div>{this.props.someReduxProperty1}</div>
<div>{this.props.someReduxProperty2}</div>
<div>{this.props.someReduxProperty3}</div>
<a onClick={this.props.someAction1}>Action1</a>
<a onClick={this.props.someAction2}>Action2</a>
<a onClick={this.props.someAction3}>Action3</a>
</Fragment>
}
}
export default connect(
(state, ownProps) => {
return {
someReduxProperty1: selectors.getSomeReduxProperty1(state),
someReduxProperty2: selectors.getSomeReduxProperty2(state),
someReduxProperty3: selectors.getSomeReduxProperty3(state)
}
},
(dispatch) => {
return {
someAction1: () => {
dispatch(someAction1())
},
someAction2: () => {
dispatch(someAction2())
},
someAction3: () => {
dispatch(someAction3())
}
}
}
)(MyComponent)
Это выполняет свою работу, но кажется, что я постоянно печатаю одни и те же вещи, даже в этом тривиально коротком примере. Компоненты моего контейнера кажутся довольно многословными к тому времени, когда они функционируют. Кроме того, я обнаружил, что часто изменяю список свойств и действий, используемых в компоненте, что немного утомляет постоянный ввод всего этого заново. Однако большинство примеров, которые я читал о react + redux, похоже, отражают эту настройку кода.
Это действительно необходимо? Я подумываю игнорировать то, что кажется лучшими практиками React + Redux, и просто передавать state
и dispatch
в качестве реквизита для моих компонентов:
import selectors from '../store/selectors'
import someAction1 from '../actions/someAction1'
import someAction2 from '../actions/someAction2'
import someAction3 from '../actions/someAction3'
class MyComponent extends React.Component {
render() => {
const { state, dispatch } = this.props
return <Fragment>
<div>{selectors.getSomeReduxProperty1(state)}</div>
<div>{selectors.getSomeReduxProperty2(state)}</div>
<div>{selectors.getSomeReduxProperty3(state)}</div>
<a onClick={() => { dispatch(someAction1()) }}>Action1</a>
<a onClick={() => { dispatch(someAction2()) }}>Action2</a>
<a onClick={() => { dispatch(someAction3()) }}>Action3</a>
</Fragment>
}
}
export default connect(
(state, ownProps) => {
return { state: state }
}
/* dispatch gets added by default */
)(MyComponent)
Код имеет только минимальное повторение имен переменных. Дополнительный бонус, поскольку вызов соединения будет одинаковым для каждого компонента, я мог бы просто подключить помощника и еще больше сократить свои компоненты:
export default connectHelper = (componentClass) => {
return connect((state) => {
return { state: state }
})(componentClass)
}
class MyComponent extends React.Component {
...
}
export default connectHelper(MyComponent)
Я теряю возможность сразу увидеть, какие свойства используются в моем магазине Redux, просто пропустив вызов connect
. Я в порядке с этим.
Итак, мой вопрос (ы):
Есть ли какие-либо другие соображения, которыми я бы пожертвовал, по существу, в обход mapStatetoProps? Меня беспокоит то, что, поскольку существует только одно свойство
state
, React может чрезмерно усердно перерисовывать каждый компонент каждый раз, когда изменяется какое-либо свойство в хранилище Redux. Поэтому необходимо сопоставлять свойства вручную в mapStateToProps?Что я теряю, пропуская mapDispatchToProps и используя введенный по умолчанию
this.props.dispatch
? Мне нужно выполнить «дополнительную» работу, чтобы отобразить состояния непосредственно в mapDispatchToProps; что я получу за эти усилия?Существуют ли другие организации/шаблоны кода, которые помогают уменьшить беспорядок свойств компонентов в настройке React+Redux?
Спасибо! Просто голова кружится вокруг этих инструментов. Это было веселое упражнение, но некоторые вещи казались немного причудливыми!