Сводка нашего чата на реактивлюкс:
Чтобы ответить на ваш вопрос: как бы вы решили это? -> Компоненты высокого порядка
Ваш вопрос сводится к тому, чтобы "повторно использовать выборку всех пользователей перед загрузкой компонента".
Допустим, вы хотите показать Компонент после загрузки ваших пользователей, в противном случае вы показываете загрузочный div: (Простая версия)
import {connect} из'act-redux '
const withUser = connect(
state => ({
users: state.users // <-- change this to get the users from the state
}),
dispatch => ({
loadUsers: () => dispatch({type: 'LOAD_USERS'}) // <-- change this to the proper dispatch
})
)
теперь вы можете повторно использовать withUsers
для обоих ваших компонентов, что будет выглядеть так:
class Content extends Component {
componentDidMount() {
if (! this.props.users || ! this.props.users.length) {
this.props.loadUsers()
}
}
// ... etc
}
const ContentWithUsers = withUsers(Content) // <-- you will use that class
class Details extends Component {
componentDidMount() {
if (! this.props.users || ! this.props.users.length) {
this.props.loadUsers()
}
}
}
const DetailsWithUsers = withUsers(Details) // <-- same thing applies
мы теперь создали повторно используемый HOC от connect. вы можете обернуть ваши компоненты с помощью withUsers, а затем использовать его повторно, но, как видите, вы также дважды переписываете компонент componentDidMount ()
давайте возьмем фактическую load if we haven't loaded it
часть вашего компонента и поместим ее в оболочку
const withUsers = WrappedComponent => { // notice the WrappedComponent
class WithUsersHOC extends Component {
componentDidMount () {
if (!this.props.users || !this.props.users.length) {
this.props.loadUsers()
}
}
render () {
if (! this.props.users) { // let's show a simple loading div while we haven't loaded yet
return (<div>Loading...</div>)
}
return (<WrappedComponent {...this.props} />) // We render the actual component here
}
}
// the connect from the "simple version" re-used
return connect(
state => ({
users: state.users
}),
dispatch => ({
loadUsers: () => dispatch({ type: 'LOAD_USERS' })
})
)(WithUsersHOC)
}
Теперь вы можете просто сделать:
class Content extends Component {
render() {
// ......
}
}
const ContentWithUsers = withUsers(Content)
Больше не нужно загружать пользователей, поскольку WithUsersHOC
позаботится об этом
Теперь вы можете обернуть Content
и Details
одним и тем же HOC (High Order Component)
Пока пользователи не будут загружены, пока не будет показан фактический компонент.
После загрузки пользователей ваши компоненты отображаются правильно.
Нужна еще одна страница, где вам нужно загрузить пользователей перед отображением? Оберните это также в свой HOC
теперь, еще одна вещь, которая вдохновляет на повторное использование
Что если вы не хотите, чтобы ваш компонент withLoading мог просто обрабатывать пользователей?
const withLoading = compareFunction = Component =>
class extends React.Component {
render() {
if (! compareFunction(this.props)) {
return <Component {...this.props} />;
}
else return <div>Loading...</div>;
}
};
теперь вы можете использовать его снова:
const withUsersLoading = withLoading(props => !props.users || ! props.users.length)
const ContentWithUsersAndLoading = withUsers(withUsersLoading(Content)) // sorry for the long name
или, написано как немного более чистая композиция:
export default compose(
withUsers,
withLoading(props => !props.users || !props.users.length)
)(Content)
теперь у вас есть и withUsers
, и withLoading
для повторного использования в вашем приложении