为什么 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 所说,App
的 useEffect()
可能是最好的)并有条件地渲染。
最后但并非最不重要的一点是,这就是您不应该完全依赖 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;
我在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 所说,App
的 useEffect()
可能是最好的)并有条件地渲染。
最后但并非最不重要的一点是,这就是您不应该完全依赖 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;