简体   繁体   English

React 不会刷新 LocalStorage 中的 state

[英]React doesn't refresh state in LocalStorage

how are you?你好吗?

Im doing a proof of concept using React and Cognito Hosted UI.我正在使用 React 和 Cognito 托管 UI 进行概念验证。 I have this code here using react router dom:我在这里使用反应路由器 dom 有此代码:

return (
      <div>
        <main>
          <Switch>
          < Route path='/' exact>
              {
              (localStorage.getItem('access_token') && localStorage.getItem('access_token')!=='undefined') ? history.replace('/home'): (
                <div>
                  <b>You are not logged in Igor, please log in using Google or User and Password. </b>
                  <b></b>
                  <a href="https://<MY_DOMAIN>.auth.us-east-1.amazoncognito.com/login?client_id=<MY_CLIENT_ID>&response_type=code&scope=aws.cognito.signin.user.admin+email+openid+phone+profile&redirect_uri=<MY_CLOUDFRONT_DISTRIBUTION_APEX>">Sign in</a>
                </div>
              )
              }
            </Route>
            <Route path='/calculator'>
              <Calculator/>
            </Route>
            <Route path='/home/'>
              <Welcome/>
            </Route>
            <Route path='/welcome/'>
              <RedirectPage/>
            </Route>
          </Switch>
        </main>
      </div>
    ); 

Im using S3 as a static website hosting, thats why i point to S3 cloudfront distribution apex.我使用 S3 作为 static 网站托管,这就是为什么我指向 S3 云端分发顶点。 Then, in my App function (residex inside App.js file), i make this validation every times the user access, to verify if this comes from a redirect, and if comes, i exchange the auth_code for a JWT token, that will be used with API Gateway:然后,在我的应用程序 function(App.js 文件中的 residex)中,我每次用户访问时都进行此验证,以验证这是否来自重定向,如果出现,我将 auth_code 交换为 JWT 令牌,这将是与 API 网关一起使用:

      const location = useLocation();
      const history = useHistory();
      let authCode = new URLSearchParams(location.search).get('code');
      console.log(authCode)

      if(authCode){
        fetch('https://<GATEWAY_ID>.execute-api.us-east-1.amazonaws.com/dev/auth',{
              method: 'POST',
              body: JSON.stringify(authCode),
              headers: {
                'Content-Type': 'application/json'
              }
            }).then((res)=>{return res.json()}).then(data=>{
              console.log('access token is:');
              console.log(data.result['access_token']);
              console.log('id token is:');
              console.log(data.result['id_token']);
              localStorage.setItem('access_token',data.result['access_token']);
              history.replace('/home')
            });
      }

The problem is that after i make the authentication, either using google or login and password, i receive the code, i authenticate on cognito using a lambda on backend (on /dev/auth route, behind the Gateway), the lambda performs the authentication well, but my frontend page enters in a loop, and after print null a bunch of times (from the line console.log(authCode), i receive an error, telling that im in a loop).问题是,在我使用谷歌或登录名和密码进行身份验证后,我收到代码,我在后端使用 lambda(在 /dev/auth 路由上,网关后面)在 cognito 上进行身份验证,lambda 执行身份验证好吧,但是我的前端页面进入了一个循环,并且在打印 null 很多次之后(从 console.log(authCode) 行,我收到一个错误,告诉我在一个循环中)。 Im very newbie in react, im doing this POC to understand the concept and to show this proccess to a client.我是反应的新手,我做这个 POC 是为了理解这个概念并向客户展示这个过程。

Thanks in advance.提前致谢。 I can't share the code as entire because that are stored in private company repository.我无法完整共享代码,因为它们存储在私人公司存储库中。

My complete code:我的完整代码:

import React from 'react';
import { Route, Switch } from 'react-router-dom';
import Calculator from './pages/Calculator';
import Welcome from './pages/Welcome';
import {useHistory, useLocation} from 'react-router-dom';
import RedirectPage from './pages/Loading';

function App() {
      const location = useLocation();
      const history = useHistory();
      let authCode = new URLSearchParams(location.search).get('code');
      console.log(authCode)

      if(authCode){
        fetch('https://<GATEWAY_ID>.execute-api.us-east-1.amazonaws.com/dev/auth',{
              method: 'POST',
              body: JSON.stringify(authCode),
              headers: {
                'Content-Type': 'application/json'
              }
            }).then((res)=>{return res.json()}).then(data=>{
              console.log('access token is:');
              console.log(data.result['access_token']);
              console.log('id token is:');
              console.log(data.result['id_token']);
              localStorage.setItem('access_token',data.result['access_token']);
              history.replace('/home')
            });
      }
    
    return (
      <div>
        <main>
          <Switch>
          < Route path='/' exact>
              {
              (localStorage.getItem('access_token') && localStorage.getItem('access_token')!=='undefined') ? history.replace('/home'): (
                <div>
                  <b>You are not logged in Igor, please log in using Google or User and Password. </b>
                  <b></b>
                  <a href="<HOSTED_UI_COGNITO>">Sign in</a>
                </div>
              )
              }
            </Route>
            <Route path='/calculator'>
              <Calculator/>
            </Route>
            <Route path='/home/'>
              <Welcome/>
            </Route>
            <Route path='/welcome/'>
              <RedirectPage/>
            </Route>
          </Switch>
        </main>
      </div>
    ); 
}

export default App;

I can see that you have written you api call code inside a functional component and i am assuming you want hit the api only once to achieve that you can write ur code inside useEffect我可以看到您已经在功能组件中编写了 api 调用代码,我假设您只想点击 api 一次以实现您可以在 useEffect 中编写您的代码

 useEffect(()=>{
    if(authCode){
        fetch('https://<GATEWAY_ID>.execute-api.us-east-1.amazonaws.com/dev/auth',{
              method: 'POST',
              body: JSON.stringify(authCode),
              headers: {
                'Content-Type': 'application/json'
              }
            }).then((res)=>{return res.json()}).then(data=>{
              console.log('access token is:');
              console.log(data.result['access_token']);
              console.log('id token is:');
              console.log(data.result['id_token']);
              localStorage.setItem('access_token',data.result['access_token']);
              history.replace('/home')
            });
      }
    
    },[])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM