Prop drilling 是通过许多中间组件传递数据,这些组件本身不使用这些数据,只是为了将其传递给确实需要它的深层嵌套组件。这很繁琐,并且使组件与他们不关心的数据紧密耦合。
问题
jsx
() {
[user] = ({ : });
;
}
() {
;
}
() {
;
}
() {
;
}
Layout、Header 和 Nav 都必须接受并转发 user,即使它们不使用它——这很冗长、容易出错(重命名prop后需要编辑每一层),并且将不相关的组件耦合在一起。
const UserContext = createContext(null);
function App() {
const [user] = useState({ name: "Ann" });
return (
<UserContext.Provider value={user}> {/* provide once at the top */}
<Layout /> {/* no user prop needed anywhere */}
</UserContext.Provider>
);
}
function Avatar() {
const user = useContext(UserContext); // consume directly, skip the middle
return <img alt={user.name} />;
}
Context 让任何后代直接读取该值,绕过中间层。
✓ Context API → for app-wide/subtree data (theme, user, locale)
✓ State libraries → Zustand/Redux/Jotai — components subscribe to the store directly
✓ Component composition → pass JSX as children instead of data through props
// composition: let the parent compose the tree, passing the leaf directly
<Layout><Nav><Avatar user={user} /></Nav></Layout>
A little prop drilling (1–2 levels) is FINE and often clearer than adding Context.
Reach for Context/stores when drilling becomes deep or widespread.
Prop drilling 是一个常见的痛点,表明数据需要被广泛使用——认识到这一点告诉你何时应该使用 Context、状态库或组合。
避免它(当它确实很深时)可以保持组件解耦和可维护性。
但判断很重要:浅层 drilling 是可以接受的,也比过早抽象更简单;目标是消除深层、重复的转发,而不是所有的 prop 传递。
一个包含详细解答的 IT 面试题库——从初级到高级。
捐赠