В моем компоненте 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)