为什么 React 刷新页面后才从 localStorage 获取正确的数据

Why it gets the correct data from localStorage only after refreshing the page in React

我在React中很长时间都无法处理这个问题,我请求你的帮助。我将不胜感激。你要成为我的英雄吗? :)) 问题是我想将角色从 RoleConnecton 分配给 localStorage,然后渲染适合该角色的组件。 但是,这只会在页面刷新后发生。我不知道如何在不需要刷新页面的情况下解决这个问题。

App.js ->

const App = () => {
    const { user, isAuthenticated } = useAuth0();
    
      return (
        isAuthenticated && (
        <>
        <RoleConnection />
          <Admin dataProvider={jsonServerProvider('Link to database here')} i18nProvider={i18nProvider}>
    {permissions =>[
      localStorage.getItem("role") ==="medic"
      ?
      <Resource name="employee" list={EmployeeList} edit={EmployeeEdit} create={EmployeeCreate} icon={WorkRounded}/>
      : null,
      <Resource name="hospital" list={HospitalList} edit={HospitalEdit} create={HospitalCreate} icon={LocalHospitalRounded}/>,
      localStorage.getItem("role") === "doctor"
      ? <Resource name="order" list={OrderList} edit={OrderEdit} create={OrderCreate} icon={PersonRounded}/>
      : null,
      localStorage.getItem("role") === "medic"
      ? <Resource name="order" list={OrderList} edit={OrderEditMedic} create={OrderCreateMedic} icon={LocalHospitalRounded}/>
      : null,
      <Resource name="patient" list={PatientList} edit={PatientEdit} create={PatientCreate} icon={PersonRounded}/>,
    ]}
          </Admin>
          <LogoutButton />
          </>
        )
      );
    };
    export default App;

角色连接 ->

import React from 'react';
import { useAuth0 } from "@auth0/auth0-react";

const RoleConnection = () => {
  const { user, isAuthenticated } = useAuth0();
  const auth_id = 'Auth ID HERE';
  fetch(`Link to Auth0/api/v2/users/${user.sub}/roles`, {
    method: 'get',
    headers: new Headers({
      'Authorization': `Bearer ${auth_id}`
    })
  })
    .then(response => response.json())
    .then(data => {
      let role = data[0].name;
      localStorage.setItem('role', role);


  });

编辑后 - 感谢特别的人

App.js

const App = () => {
const { user, isAuthenticated } = useAuth0();
const [ role, setRole ] = useState(null)

   useEffect(() => {
     if(user) auth()
  },[user])

  const auth = () => {
    fetch(`Link to Auth0/api/v2/users/${user?.sub}/roles`, {
        method: 'get',
        headers: new Headers({
           'Authorization': `Bearer ${auth_id}`
        })
     })
    .then(response => response.json())
    .then(data => {
      console.log("Data: " + data[0].name)
      setRole(data[0].name)

  });

  
  }
  console.log("Check Role: "+ role);
  return (
    isAuthenticated && (
    <>
    
      <Admin dataProvider={jsonServerProvider('Link to database here')} i18nProvider={i18nProvider}>
{permissions =>[
  console.log("Role "+ role),
  role =="medic"
  ?
  <Resource name="employee" list={EmployeeList} edit={EmployeeEdit} create={EmployeeCreate} icon={WorkRounded}/>
  : null,
  <Resource name="hospital" list={HospitalList} edit={HospitalEdit} create={HospitalCreate} icon={LocalHospitalRounded}/>,
  role === "doctor"
  ? <Resource name="order" list={OrderList} edit={OrderEdit} create={OrderCreate} icon={PersonRounded}/>
  : null,
  role === "medic"
  ? <Resource name="order" list={OrderList} edit={OrderEditMedic} create={OrderCreateMedic} icon={LocalHospitalRounded}/>
  : null,
  <Resource name="patient" list={PatientList} edit={PatientEdit} create={PatientCreate} icon={PersonRounded}/>,
]}
      </Admin>
      <LogoutButton />
      </>
    )
  );
};
export default App;

此时没有报错,只是没有显示相关栏目。 从登录控制台,您可以推断出角色中输入了空值。 但是,我查资料的时候,居然有一个角色是应该分配的。 有谁知道如何解决这个问题?

这实际上是对组件的滥用。这个 RoleConnection - 它 return 有什么(任何 JSX)吗?如果不是,则不应渲染。

您可以将其功能(获得 role 并将其设置为 localStorage 的功能)放在某处(正如@FelixKling 所说,AppuseEffect() 可能是最好的)并有条件地渲染。

最后但并非最不重要的一点是,这就是您不应该完全依赖 localStorage 的原因。我要做的是将此 role 也设置为 React 变量(例如,在状态中)。这样你就可以用这个 role 作为依赖来写一个 useEffect()

你这样做是反模式的。你应该将整个登录移动到 App 本身。

App.js

const App = () => {
const { user, isAuthenticated } = useAuth0();
const [ role, setRole ] = useState(null)

   useEffect(() => {
     if (user) auth()
  },[user])

  const auth = () => {
    fetch(`Link to Auth0/api/v2/users/${user?.sub}/roles`, {
        method: 'get',
        headers: new Headers({
           'Authorization': `Bearer ${auth_id}`
        })
     })
    .then(response => response.json())
    .then(data => {
      setRole(data[0].name)

  });

  
  }

  return (
    isAuthenticated && (
    <>
    
      <Admin dataProvider={jsonServerProvider('Link to database here')} i18nProvider={i18nProvider}>
{permissions =>[
  role ==="medic"
  ?
  <Resource name="employee" list={EmployeeList} edit={EmployeeEdit} create={EmployeeCreate} icon={WorkRounded}/>
  : null,
  <Resource name="hospital" list={HospitalList} edit={HospitalEdit} create={HospitalCreate} icon={LocalHospitalRounded}/>,
  role === "doctor"
  ? <Resource name="order" list={OrderList} edit={OrderEdit} create={OrderCreate} icon={PersonRounded}/>
  : null,
  role === "medic"
  ? <Resource name="order" list={OrderList} edit={OrderEditMedic} create={OrderCreateMedic} icon={LocalHospitalRounded}/>
  : null,
  <Resource name="patient" list={PatientList} edit={PatientEdit} create={PatientCreate} icon={PersonRounded}/>,
]}
      </Admin>
      <LogoutButton />
      </>
    )
  );
};
export default App;