前言
useOutletContext
是 React Router v6
中用于在父路由和嵌套子路由
之间共享数据 的钩子函数。
它允许父路由通过 <Outlet>
组件传递上下文(context)
,子路由则可以访问这些数据。
一、useOutletContext 核心用途
1.1、跨层级组件通信:
父路由向嵌套的子路由传递数据
1.2、避免 Props Drilling:
无需手动逐层传递 `props`
1.3、动态数据共享:
当子路由需要访问父路由的状态或方法时
二、 useOutletContext 使用说明
2.1、 父路由设置上下文
通过 <Outlet context={value}>
传递数据
javascript
// 父路由组件 Parent.jsx
import { Outlet } from 'react-router-dom';
export default function Parent() {
const [count, setCount] = useState(0);
// 定义要共享的数据和方法
const contextValue = {
count,
increment: () => setCount(c => c + 1),
reset: () => setCount(0)
};
return (
<div>
<h2>父组件 (Count: {count})</h2>
{/* 关键:通过 context 属性传递数据 */}
<Outlet context={contextValue} />
</div>
);
}
2.2、 子路由获取上下文
使用 useOutletContext()
获取父路由传递的数据
javascript
// 子路由组件 Child.jsx
import { useOutletContext } from 'react-router-dom';
export default function Child() {
// 获取父路由传递的上下文
const { count, increment, reset } = useOutletContext();
return (
<div>
<h3>子组件</h3>
<p>来自父组件的计数: {count}</p>
<button onClick={increment}>增加计数</button>
<button onClick={reset}>重置</button>
</div>
);
}
2.3、 路由配置
javascript
// 路由配置
import { createBrowserRouter } from 'react-router-dom';
const router = createBrowserRouter([
{
path: '/parent',
element: <Parent />,
children: [
{
path: 'child', // 完整路径:/parent/child
element: <Child />
}
]
}
]);
三、useOutletContext 实际应用场景示例
3.1、用户面板共享用户数据
javascript
// 父路由 UserDashboard.jsx
function UserDashboard() {
const [user, setUser] = useState(null);
useEffect(() => {
// 模拟API请求
fetchUser().then(data => setUser(data));
}, []);
const context = { user, updateProfile: handleUpdate };
return (
<div className="dashboard">
<Sidebar />
<Outlet context={context} />
</div>
);
}
// 子路由 Profile.jsx
function Profile() {
const { user, updateProfile } = useOutletContext();
return (
<div>
<h1>{user.name}'s Profile</h1>
<button onClick={() => updateProfile({ ... })}>
更新资料
</button>
</div>
);
}
// 子路由 Settings.jsx
function Settings() {
const { user } = useOutletContext();
return (
<div>
<h2>安全设置</h2>
<p>登录邮箱: {user.email}</p>
</div>
);
}
四、useOutletContext 高级用法:类型安全(TypeScript
)
javascript
// 定义上下文类型
type UserContextType = {
user: User;
updateProfile: (data: Partial<User>) => void;
};
// 父组件
<Outlet context={context satisfies UserContextType} />
// 子组件
const { user } = useOutletContext<UserContextType>();
五、useOutletContext
注意事项
- 作用域限制:只能获取直接父路由通过
<Outlet>
传递的上下文 - 响应式更新:上下文值变化会自动触发子组件重渲染
- 多层嵌套:如需跨多级传递,需每层手动转发上下文
六、备选方案:
简单场景可用 useContext +
自定义 Context
,复杂应用推荐状态管理库
javascript
// 多层嵌套示例
function Grandparent() {
return (
<Outlet context={{ layer: 'grandparent' }} />
);
}
function Parent() {
const grandparentCtx = useOutletContext();
return (
<Outlet context={{ ...grandparentCtx, layer: 'parent' }} />
);
}
function Child() {
const ctx = useOutletContext(); // { layer: 'parent' }
}
使用 useOutletContext
我们可以优雅地解决 React Router 嵌套路由间的数据传递问题,保持组件解耦的同时实现高效通信。