首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >反应中的持久记忆

反应中的持久记忆
EN

Stack Overflow用户
提问于 2021-09-02 14:17:17
回答 2查看 130关注 0票数 0

下面是我的代码,我通过道具将auth状态和令牌传递给其他组件:问题是当我刷新页面时,它会将我重定向到主页。

这是我的代码:

代码语言:javascript
复制
class App extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            account: {
                email: "",
                password: ""
            },
           
            token: "",
            auth: false
        };

    }
    
    
    confirm = async (email) => {
            let result;
            let stateAccount;
            let authToken;
            let myCookie;
            let storedCookie;

            try {
                result = await axios.post(`http://localhost:5000/abc/dosomething`, {email},{withCredentials: true});

                stateAccount = this.state.account
                stateAccount.email = email;
                this.setState({stateAccount});


                console.log(result);

                if (this.state.account.email === result.data.Email && this.state.account.password === result.data.OTPCode) {
                    authToken = result.headers.accesstoken;
                    this.setState({token: authToken});

                    myCookie = this.addCookies();
                    myCookie = myCookie.split('=');
                    storedCookie = myCookie[1].trim();

                } else {
                    console.log(`Invalid Login!`);
                    
                }


                let history = this.props.history;



                if(this.state.token === storedCookie){
                    console.log("Successful Login!");
                    console.log(`found cookie: ${storedCookie}`);
                    this.setState({auth: true});
                    history.push({pathname: "/some-endpoint/abc", state: {stateAccount}});

                }else{
                    this.setState({errorMessage: "Invalid Login!"});
                }



            }catch(error){ //set this to Permission Denied in production
                console.log(`${error.data}`});
            }
        }
    
    notLoggedInhomePage = () =>{

        if(!this.state.auth) {
            return (
                <form onSubmit={this.handleSubmit}>
                        <label>Email Address</Form.Label>
                        <input type="text" value={this.state.account.email} onChange={this.handleChange} name="email"/>
                    
                        <label>Password</Form.Label>
                        <input type="password" value={this.state.account.password} onChange={this.handleChange} placeholder="Enter One Time Password" name="password"/>
                    

                    <button type="submit" onClick={() => this.someFunction(String(this.state.account.email))}>Do Something</button>
                    <button type="submit" onClick={() => this.someOtherFunction()}>Do something else</button>
                </form>
            );
        }else{
            return(<Redirect to="/logged-in-page/signed-in" />);
        }
}


      render(){

        return(
            <Router>
                {this.notLoggedInhomePage()}
                <Switch>
                    <Route path="/list" exact component={AComponent} auth={this.state.auth} account={this.state.account} token={this.state.token}  />
                </Switch>
            </Router>
        );
    }

我知道这种状态是暂时的,但是我想要做的是,当我刷新页面时,我希望用户在刷新之前保持在相同的页面上。但是,它们会被重定向回主页(即登录屏幕),因为this.state.auth将等于notLoggedInhomePage中的false。

解决上述问题的最佳解决方案是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-02 14:38:57

你可以利用 localStorage

  • 更改令牌时,将状态设置为app_state存储。
  • 检查app_state是否存在于挂载上,还是使用新的状态。

这样的东西:

代码语言:javascript
复制
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = localStorage.getItem("app_state") ?? {
      account: {
        email: "",
        password: ""
      },
      token: "",
      auth: false
    };
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.state.token !== prevState.token) { // Set a new state if token change
      localStorage.setItem("app_state", this.state);
    }
  }
...the rest of your component
票数 0
EN

Stack Overflow用户

发布于 2021-09-02 14:35:36

需要持久化的信息可以放入浏览器存储,其中包括一个authToken。您可以从两种类型的浏览器存储中选择:

  • 使用相同域的所有选项卡和窗口都可以访问localStorage ->;即使关闭了所有此类选项卡,也仍然有效;如果稍后为同一域打开新选项卡,则再次可用。
  • sessionStorage ->只能访问设置它的选项卡;一旦关闭该选项卡就会消失。

设置一个值:localStorage.token = authToken;

获取一个值:authToken = localStorage.token;

删除值:localStorage.removeItem("token");

请注意,只能存储和检索字符串。如果尝试存储字符串以外的任何内容,它将首先对其执行.toString()操作。这就是为什么通常最好在设置值时使用JSON.stringify(obj),在获取值时使用JSON.parse(valueFromStorage)

最后,不需要将令牌从存储复制到React状态。实际上,这样做可能会对您不利,因为您发出的每个API调用都会(或应该)产生一个新的新令牌,您应该再次将其放入存储中。您最不想要的是将旧令牌缓存在长期存在的组件中,因为它们在生存期届满后将不再有效。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69032034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档