При использовании Redux с React вы используете функцию mapStateToprops для доступа к хранилищу в компонентах. Обычно вы делаете что-то вроде этого:
const mapStateToProps = (state) => ({ myItem: state.myItem, myOtherItem: state.myOtherItem, }); export default connect(mapStateToProps)(MyComponent);
Это очень просто. Но эти свойства не используют ни систему React propTypes, ни свойства defaultProps.
Мне очень нравится defaultProps. Используя их, мне не нужно беспокоиться о существовании опоры или о том, подходит ли тип. Итак, я начал отображать свойства состояния следующим образом:
MyComponent.propTypes = { myItem: PropTypes.string, myOtherItem: PropTypes.string, }; MyComponent.defaultStoreProps = { myItem: '', myOtherItem: '', }; MyComponent.defaultProps = { ...MyComponent.defaultStoreProps, }; const mapStateToProps = (state) => { const stateProps = {}; Object.keys(MyComponent.defaultStoreProps).forEach(props => { stateProps[props] = MyComponent.defaultStoreProps[props]; }); return stateProps; }; export default connect(mapStateToProps)(MyComponent);
Таким образом, реквизит из магазина будет использовать систему свойств defaultProps 👍
Но у меня много редукторов, как они могут сочетаться с этим? 😱 😱
Не волнуйтесь (будьте счастливы), это версия с несколькими редукторами:
MyComponent.defaultStoreProps = { myReducer: { myItem: '' }, myOtherReducer: { myOtherItem: '' }, }; MyComponent.defaultProps = { ...MyComponent.defaultStoreProps.myReducer, ...MyComponent.defaultStoreProps.myOtherReducer, }; const mapStateToProps = (state) => { const stateProps = {}; Object.keys(MyComponent.defaultStoreProps).forEach(reducer => { const propList = Object.keys(MyComponent.defaultStoreProps[reducer]); propList.forEach(props => { stateProps[props] = MyComponent.defaultStoreProps[reducer][props]; }); }); return stateProps; };
Как видите, теперь мы определяем объект с именами редуктора в ключе.
Но этот код нужно повторять на каждом компоненте, и я очень не люблю повторяться (СУХОЙ!).
Здесь на сцену выходит компонент высшего порядка.
const withMappedProps = (WrappedComponent, defaultStoreProps) => { class MapDefaultPropsHOC extends React.PureComponent { render() { return <WrappedComponent key="wrapped" {...this.props} />; } } const mapStateToProps = (state) => { const stateProps = {}; Object.keys(defaultStoreProps).forEach(reducer => { Object.keys(defaultStoreProps[reducer]).forEach(props => { stateProps[props] = defaultStoreProps[reducer][props]; }); }); } return connect(mapStateToProps)(MapDefaultPropsHOC); };
А потом в компоненте:
MyComponent.defaultStoreProps = { myReducer: { myItem: '' }, myOtherReducer: { myOtherItem: '' }, }; MyComponent.defaultProps = { ...MyComponent.defaultStoreProps.myReducer, ...MyComponent.defaultStoreProps.myOtherReducer, }; export default withMappedProps(MyComponent, MyComponent.defaultStoreProps);
Вот и все ! Теперь нам просто нужно определить defaultStoreProps и передать его функции withMappedProps.
Следите за новыми приключениями!