如何传递函数以链接React路由器V6中的组件

发布于 2025-02-12 07:24:21 字数 2182 浏览 2 评论 0 原文

我想传递到链接组件的功能。我该怎么做?我尝试使用状态和使用状态,虽然它们在正常变量方面工作良好,但USEETOCE在尝试传递功能时会发送无效。

const function=someFunction(){}

<Link state={func:function} to="/LoginScreen" style={style.a} >
  Login
</Link>

这行不通。

试图使用反应上下文的代码:

import React, { useState } from "react";
import { Link } from "react-router-dom";

const RefreshDisplayContext = React.createContext();

function Launchpad() {
  const [launchpadState, updatelaunchpadState] = useState({
    userIsLoggedIn: false
  });

  function refreshDisplay(event) {
    updatelaunchpadState({ userIsLoggedIn: true });
  }

  return (
    <RefreshDisplayContext.Provider value={refreshDisplay}>
      <div>
        {launchpadState.userIsLoggedIn ? (
          <p>User is Logged In </p>
        ) : (
          <p>User is Not Logged In </p>
        )}

        <Link to="login" state={launchpadState}>
          Login via Child
        </Link>
      </div>
    </RefreshDisplayContext.Provider>
  );
}

export { Launchpad, RefreshDisplayContext };
import React, { useState } from "react";
import { RefreshDisplayContext } from "../routes/Launchpad";

function Login(props) {
  const refreshDisplay = React.useContext(RefreshDisplayContext);

  return (
    <button
      type="button"
      onClick={() => refreshDisplay({ userIsLoggedIn: true })}
    >
      Login
    </button>
  );
}

export { Login };
import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router-dom";

import { Launchpad } from "./routes/Launchpad";
import { Login } from "./routes/Login";

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

root.render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<Launchpad />} />
      <Route path="/login" element={<Login />} />
    </Routes>
  </BrowserRouter>
);

codesandbox

There is a function that I want to pass to a link component. How would I do it? I tried using state and useLocation and while they work good for normal variables, useLocation sends null when trying to pass down a function.

const function=someFunction(){}

<Link state={func:function} to="/LoginScreen" style={style.a} >
  Login
</Link>

This does not work.

Code trying to use a React context:

import React, { useState } from "react";
import { Link } from "react-router-dom";

const RefreshDisplayContext = React.createContext();

function Launchpad() {
  const [launchpadState, updatelaunchpadState] = useState({
    userIsLoggedIn: false
  });

  function refreshDisplay(event) {
    updatelaunchpadState({ userIsLoggedIn: true });
  }

  return (
    <RefreshDisplayContext.Provider value={refreshDisplay}>
      <div>
        {launchpadState.userIsLoggedIn ? (
          <p>User is Logged In </p>
        ) : (
          <p>User is Not Logged In </p>
        )}

        <Link to="login" state={launchpadState}>
          Login via Child
        </Link>
      </div>
    </RefreshDisplayContext.Provider>
  );
}

export { Launchpad, RefreshDisplayContext };
import React, { useState } from "react";
import { RefreshDisplayContext } from "../routes/Launchpad";

function Login(props) {
  const refreshDisplay = React.useContext(RefreshDisplayContext);

  return (
    <button
      type="button"
      onClick={() => refreshDisplay({ userIsLoggedIn: true })}
    >
      Login
    </button>
  );
}

export { Login };
import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router-dom";

import { Launchpad } from "./routes/Launchpad";
import { Login } from "./routes/Login";

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

root.render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<Launchpad />} />
      <Route path="/login" element={<Login />} />
    </Routes>
  </BrowserRouter>
);

Codesandbox

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

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

发布评论

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

评论(1

丿*梦醉红颜 2025-02-19 07:24:21

代码问题的问题是,您仅在UI/ReactTree周围渲染 REFRESHDISPLAYCONTEXT ,即 lainingpad 组件正在渲染 单击“/login” 的链接,然后该应用程序导航到该路由并渲染登录,渲染的组件是 exter
React上下文正在尝试访问,并且由于也没有默认值,因此无法从未定义的上下文值访问 REFRESHDISPLAY

解决方案

移动 REFRESHDISPLAYCONTEXT.PROVIDER 在ReactTree中更高,以便能够为所有消费者提供相同的上下文值。

创建一个新文件来声明和导出上下文。

refreshdisplay.context.js

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

export const RefreshDisplayContext = createContext({
  refreshDisplay: () => {}
});

export const useRefreshDisplay = () => useContext(RefreshDisplayContext);

const RefreshDisplayProvider = ({ children }) => {
  const [launchpadState, updatelaunchpadState] = useState({
    userIsLoggedIn: false
  });

  function refreshDisplay(event) {
    updatelaunchpadState({ userIsLoggedIn: true });
  }

  return (
    <RefreshDisplayContext.Provider value={{ launchpadState, refreshDisplay }}>
      {children}
    </RefreshDisplayContext.Provider>
  );
};

export default RefreshDisplayProvider;

导入并包装您想要访问 refreshdisplayContext 的所有组件。

index.js

import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import RefreshDisplayProvider from "./refreshDisplay.context";
import { Launchpad } from "./routes/Launchpad";
import { Login } from "./routes/Login";

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

root.render(
  <BrowserRouter>
    <RefreshDisplayProvider>
      <Routes>
        <Route path="/" element={<Launchpad />} />
        <Route path="/login" element={<Login />} />
      </Routes>
    </RefreshDisplayProvider>
  </BrowserRouter>
);

更新消费者以访问提供的上下文值。

lainingpad

import React from "react";
import { Link } from "react-router-dom";
import { useRefreshDisplay } from "../refreshDisplay.context";

export function Launchpad() {
  const { launchpadState } = useRefreshDisplay();

  return (
    <div>
      <p>
        User is {launchpadState.userIsLoggedIn ? "Logged In" : "Not Logged In"}
      </p>

      <Link to="login" state={launchpadState}>
        Login via Child
      </Link>
    </div>
  );
}

登录

import React from "react";
import { useNavigate } from "react-router-dom";
import { useRefreshDisplay } from "../refreshDisplay.context";

function Login(props) {
  const navigate = useNavigate();
  const { refreshDisplay } = useRefreshDisplay();

  return (
    <button
      type="button"
      onClick={() => {
        refreshDisplay();
        navigate("/", { replace: true });
      }}
    >
      Login
    </button>
  );
}

export { Login };

“编辑how-to-pass-a-function-to-link-link-to-link-component-to-link-component-in-reactcont-inct-router-v6”

Issue

The issue with the code is that you are only rendering the RefreshDisplayContext around the UI/ReactTree that the Launchpad component is rendering. When the link to "/login" is clicked and the app navigates to that route and renders Login, the component being rendered is outside the
React context it's trying to access, and since there's also no default value, refreshDisplay can't be accessed from the undefined context value.

Solution

Move the RefreshDisplayContext.Provider higher in the ReactTree so that it is able to provide the same context value to all consumers.

Create a new file to declare and export the context.

refreshDisplay.context.js

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

export const RefreshDisplayContext = createContext({
  refreshDisplay: () => {}
});

export const useRefreshDisplay = () => useContext(RefreshDisplayContext);

const RefreshDisplayProvider = ({ children }) => {
  const [launchpadState, updatelaunchpadState] = useState({
    userIsLoggedIn: false
  });

  function refreshDisplay(event) {
    updatelaunchpadState({ userIsLoggedIn: true });
  }

  return (
    <RefreshDisplayContext.Provider value={{ launchpadState, refreshDisplay }}>
      {children}
    </RefreshDisplayContext.Provider>
  );
};

export default RefreshDisplayProvider;

Import and wrap all the components you want to have access to the RefreshDisplayContext.

index.js

import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import RefreshDisplayProvider from "./refreshDisplay.context";
import { Launchpad } from "./routes/Launchpad";
import { Login } from "./routes/Login";

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

root.render(
  <BrowserRouter>
    <RefreshDisplayProvider>
      <Routes>
        <Route path="/" element={<Launchpad />} />
        <Route path="/login" element={<Login />} />
      </Routes>
    </RefreshDisplayProvider>
  </BrowserRouter>
);

Update the consumers to access the provided context value.

Launchpad

import React from "react";
import { Link } from "react-router-dom";
import { useRefreshDisplay } from "../refreshDisplay.context";

export function Launchpad() {
  const { launchpadState } = useRefreshDisplay();

  return (
    <div>
      <p>
        User is {launchpadState.userIsLoggedIn ? "Logged In" : "Not Logged In"}
      </p>

      <Link to="login" state={launchpadState}>
        Login via Child
      </Link>
    </div>
  );
}

Login

import React from "react";
import { useNavigate } from "react-router-dom";
import { useRefreshDisplay } from "../refreshDisplay.context";

function Login(props) {
  const navigate = useNavigate();
  const { refreshDisplay } = useRefreshDisplay();

  return (
    <button
      type="button"
      onClick={() => {
        refreshDisplay();
        navigate("/", { replace: true });
      }}
    >
      Login
    </button>
  );
}

export { Login };

Edit how-to-pass-a-function-to-link-component-in-react-router-v6

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