为啥反应组件需要刷新才能加载其内容,即使在成功登录后也是如此?

Posted

技术标签:

【中文标题】为啥反应组件需要刷新才能加载其内容,即使在成功登录后也是如此?【英文标题】:why react component require refresh to load its content ,even after successful login?为什么反应组件需要刷新才能加载其内容,即使在成功登录后也是如此? 【发布时间】:2022-01-18 20:02:54 【问题描述】:

在成功登录后的反应应用程序中,我将访问和响应令牌存储到本地存储,并使用 axios intersaptor 将令牌设置为 axios 标头,而不是在另一个页面上调用 get 请求给出 401 错误,刷新页面后它可以工作美好的。所以我的问题是,为什么这里不输入代码`不刷新也能正常工作。

登录页面

import React,useState from 'react'
import "./Login.css"
import api from "./Api.js"
export default function Login() 
  const [data,setdata]=useState([]);

 function handle(e)
     e.preventDefault();
   const name = e.target.name;
    const value = e.target.value;
    setdata(...data,[name]:value);
 

function callapi(e)
    e.preventDefault();
    console.log(data);
    api.post('http://127.0.0.1:8000/gettoken/',data)
    .then((res) =>
        console.log(res.data);
        localStorage.setItem('access',res.data.access);
        localStorage.setItem('refresh',res.data.refresh);
    
       
     ).catch((error)=>
        console.log(error);
        localStorage.removeItem('access');
        localStorage.removeItem('refresh');
      );



    return <><div className='container'>
        <form  className="formdiv">
        <div class="mb-3">
          <label for="exampleInputEmail1" class="form-label">Email address</label>
          <input type="text" class="form-control" name="username" onChange=handle id="exampleInputEmail1" aria-describedby="emailHelp"/>
          <div id="emailHelp" class="form-text">We'll never share your email with anyone else.</div>
        </div>
        <div class="mb-3">
          <label for="exampleInputPassword1" class="form-label">Password</label>
          <input type="password" class="form-control" name="password" onChange=handle id="exampleInputPassword1"/>
        </div>
        <div class="mb-3 form-check">
          <input type="checkbox" class="form-check-input" id="exampleCheck1"/>
          <label class="form-check-label" for="exampleCheck1">Check me out</label>
        </div>
        <div className='butt'>
        <button type="submit" onClick=callapi class="btn ">Submit</button></div>
      </form>
      </div>
      </>
    

api.js

import axios from "axios";

const api=axios.create(baseURL:'http://127.0.0.1:8000/');
const access=localStorage.getItem('access');
const refresh=localStorage.getItem('refresh');
api.interceptors.request.use(
    config =>
        config.headers.authorization=`Bearer $access`;
        return config;
    ,
    error=>
        return Promise.reject(error);
    
);
export default api;

另一个组件

import React ,useState,useEffect from "react";
import ImageCard from "./ImageCard";
import interviewImg from "./Images/interview.jpg";
import InterviewExperienceCard from "./InterviewExperienceCard";
import api from './Api.js';

function InterviewExperiencePage()
  const [datalist,setdatalist] = useState([]);
useEffect(() => 
  
    api.get('/experience/').then((res)=>
      setdatalist(res.data);
      console.log(res.data);
    ).catch((error)=>
      console.log(error);
    );
    
,[]);

【问题讨论】:

尝试使用 axios.defaults.headers = 逻辑,而不是创建 axios 实例并在其他任何地方使用它 【参考方案1】:

这里的问题看起来是您在登录之前设置访问和刷新令牌值,然后不允许它们更改。您可以将值替换为函数。

const access = () => localStorage.getItem('access');
const refresh = () => localStorage.getItem('refresh');
api.interceptors.request.use(
    config =>
        config.headers.authorization=`Bearer $access()`;
        return config;
    ,
    error=>
        return Promise.reject(error);
    
);

我要指出的是,从安全的角度来看,将您的访问和刷新令牌存储在本地存储中并不是一个好的做法。我可能会将访问令牌存储在内存中,而刷新令牌应该是仅安全的 http cookie。令牌安全性存在很多陷阱,因此我建议您进行更多研究以使您的代码生效。

【讨论】:

以上是关于为啥反应组件需要刷新才能加载其内容,即使在成功登录后也是如此?的主要内容,如果未能解决你的问题,请参考以下文章

即使道具没有改变,为啥还要对重新渲染组件做出反应?

反应表 - 不刷新内容

JWT, 为啥需要刷新令牌?

使用带有反应的谷歌登录按钮

在浏览器上点击刷新后反应路由器 v4 登录检查

为啥图片预加载无效?