通常,您将通过 props 将信息从父组件传递到子组件。但是,如果必须将道具传递到中间的许多组件,或者应用中的许多组件需要相同的信息,则传递道具可能会变得冗长且不方便。Context 允许父组件将一些信息提供给其下树中的任何组件(无论其深度如何),而无需通过 prop 显式传递它。
传递道具的问题
传递道具是将数据通过 UI 树显式传递到使用它的组件的好方法。
但是,当您需要将一些道具深入树中传递时,或者如果许多组件需要相同的道具时,传递道具可能会变得冗长和不方便。最接近的共同祖先可能与需要数据的组件相距甚远,将状态提升到如此高的水平可能会导致一种称为“支柱钻孔”的情况。
如果有一种方法可以在不传递道具的情况下将数据“传送”到树中需要它的组件,那不是很好吗?有了 React 的上下文功能,就有了!
上下文:传递道具的替代方案
Context 允许父组件向其下的整个树提供数据。上下文有很多用途。下面是一个例子。考虑以下接受 a 大小的组件:Heading
level
import Heading from './Heading.js'; import Section from './Section.js'; export default function Page() { return ( <Section> <Heading level={1}>Title</Heading> <Heading level={2}>Heading</Heading> <Heading level={3}>Sub-heading</Heading> <Heading level={4}>Sub-sub-heading</Heading> <Heading level={5}>Sub-sub-sub-heading</Heading> <Heading level={6}>Sub-sub-sub-sub-heading</Heading> </Section> ); }
export default function Section({ children }) { return ( <section className="section"> {children} </section> ); }
export default function Heading({ level, children }) { switch (level) { case 1: return <h1>{children}</h1>; case 2: return <h2>{children}</h2>; case 3: return <h3>{children}</h3>; case 4: return <h4>{children}</h4>; case 5: return <h5>{children}</h5>; case 6: return <h6>{children}</h6>; default: throw Error('Unknown level: ' + level); } }
假设您希望同一标题中的多个标题始终具有相同的大小:Section
import Heading from './Heading.js'; import Section from './Section.js'; export default function Page() { return ( <Section> <Heading level={1}>Title</Heading> <Section> <Heading level={2}>Heading</Heading> <Heading level={2}>Heading</Heading> <Heading level={2}>Heading</Heading> <Section> <Heading level={3}>Sub-heading</Heading> <Heading level={3}>Sub-heading</Heading> <Heading level={3}>Sub-heading</Heading> <Section> <Heading level={4}>Sub-sub-heading</Heading> <Heading level={4}>Sub-sub-heading</Heading> <Heading level={4}>Sub-sub-heading</Heading> </Section> </Section> </Section> </Section> ); }
export default function Section({ children }) { return ( <section className="section"> {children} </section> ); }
export default function Heading({ level, children }) { switch (level) { case 1: return <h1>{children}</h1>; case 2: return <h2>{children}</h2>; case 3: return <h3>{children}</h3>; case 4: return <h4>{children}</h4>; case 5: return <h5>{children}</h5>; case 6: return <h6>{children}</h6>; default: throw Error('Unknown level: ' + level); } }
目前,您将 prop 分别传递给每个:level
<Heading>
<Section> <Heading level={3}>About</Heading> <Heading level={3}>Photos</Heading> <Heading level={3}>Videos</Heading> </Section>
如果您可以将 prop 传递给组件并将其从 .这样,您可以强制同一部分中的所有标题都具有相同的大小:level
<Section>
<Heading>
<Section level={3}> <Heading>About</Heading> <Heading>Photos</Heading> <Heading>Videos</Heading> </Section>