You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS中兄弟组件间如何传递函数?附场景代码

解决方案:状态提升+父组件中转

React路由的state仅支持传递可序列化的数据(如字符串、数字、普通对象),函数无法被序列化,所以用useLocation传递函数的思路行不通。最直接的解决方式是采用状态提升,把共享状态和回调函数转移到两个组件的共同父组件中,再通过props分别传递给NavBar和Login。

步骤1:改造共同父组件

假设父组件是App.js,将NavBar里的登录状态和userLog逻辑迁移到这里:

import { useState } from 'react';
import NavBar from './NavBar';
import Login from './Login';
import { Routes, Route } from 'react-router-dom';

function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  // 原NavBar中的userLog函数,移至父组件
  const userLog = () => {
    setIsLoggedIn(true);
    // 保留原userLog中的其他业务逻辑
  };

  return (
    <div>
      <NavBar isLoggedIn={isLoggedIn} />
      <Routes>
        {/* 通过props将userLog传递给Login组件 */}
        <Route path="/login" element={<Login userLog={userLog} />} />
        {/* 其他路由配置 */}
      </Routes>
    </div>
  );
}

export default App;

步骤2:改造NavBar组件

NavBar不再维护自身状态,直接使用父组件传递的isLoggedIn渲染对应内容:

function NavBar({ isLoggedIn }) {
  return (
    <nav>
      {isLoggedIn ? (
        <span>已登录</span>
      ) : (
        <a href="/login">去登录</a>
      )}
    </nav>
  );
}

export default NavBar;

步骤3:改造Login组件

登录成功后直接调用父组件传递的userLog更新全局状态:

function Login({ userLog }) {
  const handleLogin = () => {
    // 模拟登录请求逻辑
    fetch('/api/login', { method: 'POST', body: JSON.stringify({/* 登录参数 */}) })
      .then(res => res.json())
      .then(() => {
        // 登录成功后触发状态更新
        userLog();
        // 跳转至首页或目标页面
        window.location.href = '/';
      });
  };

  return (
    <button onClick={handleLogin}>登录</button>
  );
}

export default Login;

替代方案:React Context(适合深层组件场景)

如果NavBar和Login的组件层级较深,或需要在更多组件中共享登录状态,可以用Context封装状态逻辑:

// AuthContext.js
import { createContext, useContext, useState } from 'react';

const AuthContext = createContext();

export function AuthProvider({ children }) {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  const userLog = () => {
    setIsLoggedIn(true);
  };

  return (
    <AuthContext.Provider value={{ isLoggedIn, userLog }}>
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  return useContext(AuthContext);
}

在App.js中用Context包裹组件:

import { AuthProvider } from './AuthContext';

function App() {
  return (
    <AuthProvider>
      <NavBar />
      <Routes>
        <Route path="/login" element={<Login />} />
      </Routes>
    </AuthProvider>
  );
}

NavBar中通过自定义Hook获取状态:

import { useAuth } from './AuthContext';

function NavBar() {
  const { isLoggedIn } = useAuth();
  return (
    <nav>
      {isLoggedIn ? <span>已登录</span> : <a href="/login">去登录</a>}
    </nav>
  );
}

Login中通过自定义Hook获取回调函数:

import { useAuth } from './AuthContext';

function Login() {
  const { userLog } = useAuth();

  const handleLogin = () => {
    // 登录逻辑...
    userLog();
  };

  return <button onClick={handleLogin}>登录</button>;
}

内容的提问来源于stack exchange,提问作者elyasaf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 03:50:37