我知道钩子只能在函数组件的主体内调用,但我想知道是否有办法从react-router@6个操作函数中访问上下文数据.我有一个操作功能,处理用户登录表单过程.我想使用来自应用程序上下文的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 }

我试图从我的操作函数内的应用程序上下文中获取setCurrentUser函数,但得到错误:无效的钩子调用.我不知所措,我真的很感激你把我推向正确的方向.

我希望实现的是,在成功登录后,更新我的应用程序上下文与当前登录的用户信息.

推荐答案

如果在react 树中呈现比RouterProvider组件更高的APPContextProvider组件,则组件呈现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>
);

APP

Update the authAction to curry a passed appContext argument and return the action function. Access appContext via the useAPPContext hook and pass to the route action creator.

import {
  createBrowserRouter,
  RouterProvider,
  json,
  redirect,
} from "react-router-dom";
import { useAPPContext } from "./app.context";

const authAction = (appContext) => async ({ request }) => {
  const { setCurrentUser } = appContext;
  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;
  }
};
export default function APP() {
  const appContext = useAPPContext();

  const router = createBrowserRouter([
    ...
    {
      path: "/login",
      element: <Login />,
      action: authAction(appContext)
    },
    ...
  ]);

  return <RouterProvider router={router} />;
}

Edit is-there-a-way-of-accessing-react-context-data-in-react-router-6-action-function

Javascript相关问答推荐

vscode扩展-webView Panel按钮不起任何作用

类型脚本中只有字符串或数字键而不是符号键的对象

我可以从React中的出口从主布局调用一个处理程序函数吗?

并不是所有的iframe都被更换

IF语句的计算结果与实际情况相反

在我的index.html页面上找不到我的Java脚本条形图

如何在.NET Core中将chtml文件链接到Java脚本文件?

try 使用PM2在AWS ubuntu服务器上运行 node 进程时出错

按什么顺序接收`storage`事件?

顶点图使用组标签更新列之间的条宽

JavaScript将字符串数字转换为整数

Pevent触发material 用户界面数据网格中的自动保存

如何让SVG图标在被点击和访问后改变 colored颜色 ,并在被访问后取消点击时恢复到原来的 colored颜色 ?

在单击按钮时生成多个表单时的处理状态

设置复选框根据选中状态输入选中值

JQuery使用选项填充HTMLSELECT并设置默认结果,默认结果显示为空

react :图表负片区域不同 colored颜色

ReactJS Sweep Line:优化SciChartJS性能,重用wasmContext进行多图表渲染

在不使用AJAX的情况下将JavaScript数组值传递给Laravel控制器?

如何在不获取其子元素的文本内容的情况下获取元素的文本内容?