Реактивный каскадный рендеринг - PullRequest
0 голосов
/ 03 июля 2018

В моем компоненте App.js реализован элемент react-toastify:

class App extends Component {
  componentDidUpdate(prevProps) {
    const { toast } = this.props
    if(toast.id !== prevProps.toast.id) {
      this.notify(toast)
    }
  }

  notify = (data) => {
    switch(data.type) {
      case TOAST.TYPE.ERROR:
        ...
        return toast.show()
    }
  }

  render() {
    return (
      <BrowserRouter> 
        <div className="app">
          <Switch>
            <Route path={ getRoutePath('password.set') } component={ PasswordSet } />
            <Route path={ getRoutePath('password.reset') } component={ PasswordReset } />
            <Route path={ getRoutePath('login') } component={ LoginSection } />
            <Route path={ getRoutePath('home') } component={ AuthenticatedSection } />
          </Switch>
          <ToastContainer 
            className="custom-toastify" 
            autoClose={ 5000 } 
            hideProgressBar={ true }
            closeButton={ <CloseButton /> } 
          />
        </div>
      </BrowserRouter>
    )
  }
}

function mapStateToProps({ toast }) {
  return { toast }
}

Теперь рассмотрим следующий сценарий: у меня есть UsersAdmin PureComponent внутри AuthenticatedSection, где вы можете включать / отключать пользователей. Когда вы нажимаете кнопку включения / выключения, компонент UsersAdmin перерисовывается из-за изменения состояния редукции users, а затем перерисовывается, потому что я показываю тост при вызове API успеха / ошибки.

toggleUsersDisabled = (user) => () => {
        const { modifyUser, showToast } = this.props
        modifyUser(user.id, {
            disabled: user.disabled === 0 ? 1 : 0
        }).then((response) => {
            showToast(`${response.value.name} has been ${response.value.disabled ? 'disabled' : 'enabled'}`)
        }).catch(_noop)
    }

showToast отправляет новое сообщение в состояние редукции для тостов. Можно ли как-то предотвратить повторное рендеринг дочерних компонентов при показе тоста?

Edit: добавлено редукс-соединение UsersAdmin, включая селектор

// users selector
import { createSelector } from 'reselect'

const getUsers = state => state.users.get('data')
const getIsFulfilled = state => state.users.get('isFulfilled')

export const getFulfilledUsers = createSelector(
    [getUsers, getIsFulfilled],
    users => users
)

// UsersAdmin
const mapStateToProps = (state) => {
    return {
        users: getFulfilledUsers(state)
    }
}


UsersAdmin.propTypes = {
    users: PropTypes.object.isRequired,
    fetchUsersList: PropTypes.func.isRequired,
    modifyUser: PropTypes.func.isRequired,
    deleteUser: PropTypes.func.isRequired,
    showToast: PropTypes.func.isRequired
}

export default connect(mapStateToProps, { fetchUsersList, modifyUser, deleteUser, showToast })(UsersAdmin)

1 Ответ

0 голосов
/ 12 июля 2018

Я не совсем понимаю, почему вы добавили все логины тостов внутри App.js

если вы просматриваете документы в: https://github.com/fkhadra/react-toastify#installation

единственное, что вам нужно сделать, это добавить <ToastContainer /> в ваше приложение, и все готово, точно так же, как в вашем примере.

Теперь для вызова тостов вы просто импортируете:

import { toast } from 'react-toastify';

к любому компоненту в системе, который вам нравится, и теперь вы просто запускаете функцию toast и получаете тост.

е:

import { Component } from 'react';
import { toast } from 'react-toastify';

class SomeComponent extends Component {
    showToast() {
        toast('you now see a toast');
    }

    render() {
        return <button onClick={()=>this.showToast()}>toast it</button>;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...