reactjs 在React Router 6 action函数中是否有访问React上下文数据的方法

h22fl7wq  于 2023-03-22  发布在  React
关注(0)|答案(2)|浏览(110)

我知道钩子只能在函数组件的主体内部调用,但我想知道是否有一种方法可以从react-router@6 action函数内部访问上下文数据。我有一个处理用户登录表单过程的action函数。我想使用来自应用程序上下文的setCurrentUser函数,以便使用从API返回的登录用户数据更新状态

export const AuthAction = async ({ request }) => {
  const { setCurrentUser } = useAppContext()
  const data = await request.formData()
  const userData = {
    email: data.get('email'),
    password: data.get('password')
  }
  if (!userData.email || !userData.password) {
    throw json(
      { message: 'Please provide all values' },
      { status: 400, statusText: 'Please provide all values' }
    )
  }
  try {
    const { data } = await axios.post('/api/auth/login', userData)
    setCurrentUser(data)
    return redirect('/')
  } catch (error) {
    return error.response.data.msg
  }
}

appContext.js

const AppContextProvider = ({ children }) => {
  const [state, dispatchFn] = useReducer(reducer, initialState)

  const setCurrentUser = (user) => {
    dispatchFn({ type: 'SET_CURRENT_USER', payload: user })
  }

  return (
    <AppContext.Provider value={{setCurrentUser}}>
      {children}
    </AppContext.Provider>
  )
}

const useAppContext = () => {
  return useContext(AppContext)
}

export { AppContextProvider, useAppContext }

我尝试在我的action函数中从应用程序上下文获取setCurrentUser函数,但我得到错误:无效的钩子调用。我很困惑,我真的很感激你能在正确的方向上推动我。
我希望实现的是,在成功登录后,用当前登录的用户信息更新我的应用程序上下文。

ee7vknir

ee7vknir1#

你是对的,钩子不能直接在像AuthAction这样的非组件函数中使用。但是,你可以将所需的上下文数据或函数作为参数传递给你的动作函数。
首先,修改AuthAction函数以接受一个附加参数setCurrentUser,并删除钩子调用:

export const AuthAction = async ({request, setCurrentUser}) => {
  // Removed the line: const {setCurrentUser} = useAppContext()
  // ...
  // Rest of the code remains the same
}

接下来,当您从组件调用AuthAction函数时,请确保从上下文传递setCurrentUser函数:

import React from 'react';
import { AuthAction } from './AuthAction';
import { useAppContext } from './AppContext';

function LoginComponent() {
  const { setCurrentUser } = useAppContext();

  const handleLogin = async (request) => {
    try {
      await AuthAction({ request, setCurrentUser });
      // ... any additional login-related logic here
    } catch (error) {
      console.error('Login failed:', error.message);
    }
  };

  // ... render your login form and handle its submission with handleLogin()
}

通过将setCurrentUser函数作为参数传递给AuthAction,现在可以在成功登录时更新上下文数据,而无需直接在AuthAction中使用钩子。

iibxawm4

iibxawm42#

如果AppContextProvider组件在ReactTree中的渲染位置高于RouterProvider组件,则渲染RouterProvider的组件可以访问AppContext值,并在路由示例化时将其传递给authAction函数。
示例:
index.js

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
import AppContextProvider from "./app.context";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
  <StrictMode>
    <AppContextProvider>
      <App />
    </AppContextProvider>
  </StrictMode>
);

应用程序
更新authAction以咖喱传递的appContext参数并返回action函数。通过useAppContext钩子访问appContext并传递给路由操作创建器。
x一个一个一个一个x一个一个二个x

相关问题