这里的想法是 redux-persist 的持久化组件负责在 localStorage 中持久化数据或 redux 状态。
为了在用户同意的基础上做出决定,需要有条件地渲染或不渲染PersistGate组件
要解决这样的问题,您可以在 Persistor 上编写一个自定义组件,该组件仅在授予权限时才呈现它。提示用户授予或拒绝权限的逻辑也可以放在同一个组件中
例子
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。其次,我们不能有条件地更改我们重新渲染的组件,否则整个应用程序都会被刷新。到目前为止,实现它的唯一方法是自己实际实现将 redux 状态保存在 localStorage 中的逻辑,并在刷新时初始获取它
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);
实现上述组件后,需要在reducer中监听PERSISTOR_HYDRATE动作,更新redux状态。
注意:您可能需要添加更多处理以使持久化和重新水化正确,但想法保持不变