使用效果仅在刷新页面后起作用

发布于 2025-02-11 21:49:11 字数 2818 浏览 0 评论 0原文

我在上下文中使用使用效果。我认为使用效果应在加载页面后运行,但是它不起作用,但是如果我刷新页面(F5),则可以使用。

我是新的使用React,但我认为它应该与Arg一样的空数组使用。

这是上下文:

import { createContext, useState, useEffect } from "react";

const PatientContext = createContext();

export const PatientsProvider = (props) => {
    const {children} = props;
    
    const [patients, setPatients] = useState([]);
    

    //get the patients from the database
    useEffect( () => {
        const url = `${import.meta.env.VITE_BACKEND_URL}/api/patients`;
        const token = localStorage.getItem("token");

        if(!token) return;

        const getPatients = async () => {
            try {
                const response = await fetch(url, {
                    method: 'GET', 
                    headers: {
                    'Content-Type': 'application/json',
                    "Authorization" : `Bearer ${token}`
                    }
                });
        
                const result = await response.json();
        
                if (!response.ok){ 
                    throw new Error(result.msg);
                }
        
                const {createdAt, __v, updatedAt, ...savedPatient} = result;

                setPatients(result)
                setLoading(false);
                
        
                } catch (error) {
                setLoading(false)
                setAlert({msg: error.message, error1: true})
                console.log(error)
                
                }
        }
        
        getPatients();
    }, [])

编辑:

现在我意识到问题是在登录页面中第一次使用效果(在我需要之前,因为在登录页面后需要它)因为PatientProvider是所有组件的父母,甚至是登录组件,但是现在我不知道如何将此提供商设置为“登录组件”。

这是我的路线:

function App() {
  return (
    <BrowserRouter>
      <AuthProvider>
        <PatientsProvider>
          <Routes>
            <Route path="/" element={< Authlayout />}>
              <Route index element={ <Login /> } />
              <Route path="sign-up" element= {<SignUp />}/>
              <Route path="forgot-password" element= {<ForgotPassword />}/>
              <Route path="forgot-password/:token" element= {<ResetPassword />}/>
              <Route path="confirm-account/:token" element= {<Confirm />}/>
            </Route>

            <Route path="/admin" element={<LoginLayout />}>
              <Route index element={<AdminPatients />} />
              <Route path="profile" element= {<Profile />}/>
              <Route path="change-password" element= {<ChangePass />}/>
            </Route>
          </Routes>
        </PatientsProvider>
      </AuthProvider>
    </BrowserRouter>
  )
}

I am using an useEffect inside a Context. I think the useEffect should run after load the page, but it does not work, but if I refresh the page(F5) then it works.

I am new Using React, but I think it should work with the empty array as arg.

This is the Context:

import { createContext, useState, useEffect } from "react";

const PatientContext = createContext();

export const PatientsProvider = (props) => {
    const {children} = props;
    
    const [patients, setPatients] = useState([]);
    

    //get the patients from the database
    useEffect( () => {
        const url = `${import.meta.env.VITE_BACKEND_URL}/api/patients`;
        const token = localStorage.getItem("token");

        if(!token) return;

        const getPatients = async () => {
            try {
                const response = await fetch(url, {
                    method: 'GET', 
                    headers: {
                    'Content-Type': 'application/json',
                    "Authorization" : `Bearer ${token}`
                    }
                });
        
                const result = await response.json();
        
                if (!response.ok){ 
                    throw new Error(result.msg);
                }
        
                const {createdAt, __v, updatedAt, ...savedPatient} = result;

                setPatients(result)
                setLoading(false);
                
        
                } catch (error) {
                setLoading(false)
                setAlert({msg: error.message, error1: true})
                console.log(error)
                
                }
        }
        
        getPatients();
    }, [])

EDIT:

Now I realized that the problem is the useEffect render the first time in the login page (before I need it, because I need it after the login page), this is happening because PatientProvider is parent of all the components even Login component, but now I do not know how to set this provider to only "after login components".

Here is my Routes:

function App() {
  return (
    <BrowserRouter>
      <AuthProvider>
        <PatientsProvider>
          <Routes>
            <Route path="/" element={< Authlayout />}>
              <Route index element={ <Login /> } />
              <Route path="sign-up" element= {<SignUp />}/>
              <Route path="forgot-password" element= {<ForgotPassword />}/>
              <Route path="forgot-password/:token" element= {<ResetPassword />}/>
              <Route path="confirm-account/:token" element= {<Confirm />}/>
            </Route>

            <Route path="/admin" element={<LoginLayout />}>
              <Route index element={<AdminPatients />} />
              <Route path="profile" element= {<Profile />}/>
              <Route path="change-password" element= {<ChangePass />}/>
            </Route>
          </Routes>
        </PatientsProvider>
      </AuthProvider>
    </BrowserRouter>
  )
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

﹏雨一样淡蓝的深情 2025-02-18 21:49:11

似乎您的令牌不是在组件安装时设置并调用此usefeft()时设置的。

我可以想到2个选项:

  1. 将您的会话数据存储在外部上下文状态,并从那里获取令牌。然后,您可以将令牌添加为useeffect()中的依赖项:
// assuming token is stored in context state 
// and will update
const {token} = useAuthContext() 
useEffect(() => {
// ...
// will be called every time the token changes
}, [token])
  1. 在此组件中订阅localstorage。 react hookz libz lib具有不错的挂钩< /a>已经写的,在此提供为简单起见:
import { useLocalStorageValue } from '@react-hookz/web'

const PatientsProvider = (props) => {
const [token] = useLocalStorageValue('token')

useEffect(() => {
// do sth with the token
}, [token])

It seems like your token is not set by the time the component mounts and calls this useEffect().

I can think of 2 options:

  1. store your session data in an outer context state and get the token from there. Then you can add token as a dependency in useEffect():
// assuming token is stored in context state 
// and will update
const {token} = useAuthContext() 
useEffect(() => {
// ...
// will be called every time the token changes
}, [token])
  1. Subscribe to localStorage in this component. react-hookz lib has a nice hook already written, providing it here for simplicity:
import { useLocalStorageValue } from '@react-hookz/web'

const PatientsProvider = (props) => {
const [token] = useLocalStorageValue('token')

useEffect(() => {
// do sth with the token
}, [token])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文