javascript - React Context Api Provider Component 在页面重新加载时丢失状态
问题描述
我只是在试验反应上下文 api,我无法在页面重新加载时保持我的状态。每当重新加载页面时,我的状态都会被设置为空。如何在我的上下文中保持状态?我可以使用 localStorage,但我不想在 localStorage 中标记,因为它有一些我不想放在那里的东西(我在这里谈论的是真实应用程序的上下文)。应用程序的流程是这个登录=>将对象传递给=>上下文提供者(通过回调函数)=>用户(通过上下文获取对象)=>在页面重新加载时我失去了状态。
应用组件
...
import React from "react";
import { HashRouter as Router, Route, Switch } from "react-router-dom";
import Login from "./login";
import User from "./user";
import Context from "../context/context";
import AppProvider from "../context/provider";
import "./styles.css";
export default class App extends React.Component {
render() {
return (
<AppProvider>
<div>
<Switch>
<Route path="/" exact component={Login} />
<Route path="/user" exact component={User} />
<Route path="*" component={() => " Not Found"} />
</Switch>
;
</div>
</AppProvider>
);
}
}
App.contextType = Context;
登录组件
...
import React from "react";
import Context from "../context/context";
import {
HashRouter as Router,
Route,
Switch,
Link,
withRouter
} from "react-router-dom";
export default class Login extends React.Component {
constructor() {
super();
this.state = {
object: {
name: "user",
age: "15",
security: "12xy"
}
};
this.submit = this.submit.bind(this);
}
submit() {
const session = this.context.setObject;
session(this.state.object);
this.props.history.push("/user");
}
render() {
console.log(this.context);
return (
<div className="App">
Login
<button onClick={this.submit}>Click me </button>
</div>
);
}
}
Login.contextType = Context;
用户组件
...
import React from "react";
import Context from "../context/context";
export default class User extends React.Component {
constructor() {
super();
this.state = {
user: [
{
name: "Johnny",
job: "Engineer"
}
]
};
this.dosubmit = this.dosubmit.bind(this);
}
componentDidMount() {
var security = this.context.object.security;
if (security !== undefined) {
console.log("security present");
} else {
console.log("not present");
}
}
dosubmit() {
localStorage.clear();
this.props.history.push("/");
}
render() {
return (
<div className="App">
{this.state.user.map(({ name, job }) => {
return (
<div>
<h1> {name}</h1>
<h2> {job} </h2>
<button onClick={this.dosubmit}>Click for logout </button>
</div>
);
})}
</div>
);
}
}
User.contextType = Context;
上下文提供者组件
...
import React, { Component, createContext } from "react";
import Context from "./context";
class AppProvider extends Component {
state = {
object: {}
};
setObject(object) {
this.setState({ object: object });
}
componentDidUpdate(prevProps, prevState) {
if (this.state.object !== prevState.object) {
localStorage.setItem("token", JSON.stringify(this.state.object));
if (this.state.object !== undefined) {
this.setState({ object: this.state.object });
}
}
}
render() {
console.log("Provider", this.state);
return (
<Context.Provider
value={{
object: this.state.object,
setObject: this.setObject.bind(this)
}}
>
{this.props.children}
</Context.Provider>
);
}
}
export default AppProvider;
...
我的示例是https://codesandbox.io/s/trusting-hertz-tql5e?file=/src/App.js
解决方案
推荐阅读
- unetstack - 中间节点在路由期间不转发所有收到的数据包
- micronaut - @MicronautTest 和 EmbeddedServer 有什么区别
- java - 使用 JAVA 在 Windows 中为自定义硬件编写 WMI 提供程序
- java - SessionNotCreatedException:会话未创建:此版本的 ChromeDriver 仅支持使用 Selenium ChromeDriver 的 Chrome 版本 77
- erlang - 如何为 Ejabberd 自定义模块生成文档?
- java - 如何保存 ArrayList
> 从返回函数? - amazon-web-services - 启动堆栈以启动 ec2 实例时出现“遇到不支持的属性 KeyName”错误
- java - Android:如何在列表视图中的吐司上显示项目 ID?
- wordpress - 我的 Wordpress 在 2 或 3 天后自动更改文件权限
- php - Cakephp 2.x Security::cipher 不提供跨两个应用程序的结果