Идея заключается в том, что персисторная составляющая резерв-перенаправителя отвечает за сохранение данных или состояния редукции в localStorage.
Чтобы принять решение на основе согласия пользователя, вам необходимо условно отобразить или нет компонент PersistGate
. Чтобы решить такую проблему, вы можете написать собственный компонент поверх Persistor, который оказывает его только тогда, когда разрешение предоставлено. Кроме того, logi c, чтобы побудить пользователя предоставить или отклонить разрешение, может go в том же компоненте
Пример
class PermissionAndPersist extends React.Component {
constructor(props) {
super(props)
this.state = {
permission: this.getCookie('userLocalStoragePermission')
}
}
getCookie(name) {
//implement the getc ookie method using document.cookie or a library
/* state returned must have the following syntax
isPermissionGranted,
isCookieExpired
*/
// The above syntax can be determined based on whether cookie is present as well as by checking the expiry data if cookie was present
}
render() {
const { permission } = this.state;
const {children, persistor} = this.props;
if(!permission.isPermissionGranted) {
// no permission granted, return a plain div/Fragment
return (
<React.Fragment>
{children}
</React.Fragment>
)
}
if(permission.isCookieExpired) {
return <Modal>{/* here goes a component which asks for user permission and on click updates the state as well as update in cookie */}</Modal>
}
// now if the cookie is present and permission is granted and cookie is not expired you render the `PersistGate` component
return <PersistGate persistor={persitor} >{children}</PersistGate>
}
}
Как только вы создадите компонент, как указано выше, вы будете рендерить его следующим образом
ReactDOM.render(
<Provider store={store}>
<PermissionAndPersist persistor={persitor} >
<MyAppRouter />
</PermissionAndPersist >
</Provider>,
document.getElementById("root")
)
Примечание: Вы всегда можете изменить реализацию компонента PermissionAndPersist в зависимости от требований, но учтите, что PeristGate должен отображаться только тогда, когда все условия совпадают. Также вы можете захотеть очистить localStorage, если пользователь не предоставляет разрешения
РЕДАКТИРОВАТЬ: Поскольку требуется фактически не повторять рендеринг всего приложения при нажатии на баннер пользователя, нам нужно внести несколько изменений.
Во-первых, повторно выполните рендеринг ModalComponent на основе условия. Во-вторых, мы не можем условно изменить компонент, который мы перерисовываем, иначе все приложение обновляется. Единственный способ добиться этого на данный момент - это на самом деле реализовать logi c для сохранения состояния избыточности в localStorage самостоятельно и получить его изначально при refre sh
class PermissionAndPersist extends React.Component {
constructor(props) {
super(props)
this.state = {
permission: this.getCookie('userLocalStoragePermission')
}
}
getCookie(name) {
//implement the getc ookie method using document.cookie or a library
/* state returned must have the following syntax
isPermissionGranted,
isCookieExpired
*/
// The above syntax can be determined based on whether cookie is present as well as by checking the expiry data if cookie was present
}
componenDidMount() {
const { permission } = this.state;
const { dispatch } = this.props;
if(permission.isPermissionGranted && !permission.isCookieExpired) {
// Idea here is to populate the redux store based on localStorage value
const state= JSON.parse(localStorage.get('REDUX_KEY'));
dispatch({type: 'PERSISTOR_HYDRATE', payload: state})
}
// Adding a listner on window onLoad
window.addEventListener('unload', (event) => {
this.persistStateInLocalStorage();
});
}
persistStateInLocalStorage = () => {
const { storeState} = this.props;
const {permission} = this.state;
if(permission.isPermissionGranted && !permission.isCookieExpired) {
localStorage.set('REDUX_KEY', JSON.stringify(storeState))
}
}
componentWillUnmount() {
this.persistStateInLocalStorage();
}
render() {
const {children} = this.props;
const {permission} = this.state;
return (
<React.Fragment>
{children}
{permission.isCookieExpired ? <Modal>{/*Pemission handling here*/}</Modal>}
</React.Fragment>
)
}
const mapStateToProps = (state) => {
return {
storeState: state
}
}
export default connect(mapStateToProps)(PermissionAndPersist);
После того, как вы реализуете вышеуказанный компонент, вам нужно прослушать действие PERSISTOR_HYDRATE
в редукторе и обновить состояние редукса.
ПРИМЕЧАНИЕ: Возможно, вам придется добавить дополнительную обработку, чтобы сделать персистенцию и регидратацию правильной, но идея остается прежним