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
相关产品推荐
相关产品推荐

