发布于 2026-01-06 0 阅读
0

像高手一样在 React 树中传递数据 😎 普通(非高手)方法是什么?对变量进行分组:使用 React Context:DEV 的全球展示挑战赛,由 Mux 呈现:展示你的项目!

像个高手一样在 React 树中传递数据 😎

正常(非BOSS)方法是什么?

将它们分组为变量:

使用 React Context:

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

嘿👋,欢迎回到我的博客。这次,我们来看看如何像个高手一样在 React 组件树中传递数据😎

正常(非BOSS)方法是什么?

我们先来看最简单的方法。直接将数据作为 props 传递到整个组件树中。假设有这样一个场景:我们有一个名为StatusComponent 的组件,它渲染一段简单的文本来描述应用程序的状态。对于我们的示例应用程序,组件树结构如下:

我们示例应用程序的组件树:

-> 应用
-> -> 首页
-> -> -> 侧边栏
-> -> -> -> 状态组件

当然,我这里只是举个简单的例子。实际应用中,组件可能多达几十个。这意味着,如果采用非最优方案,可能会对代码的可维护性和可读性造成极其不利的影响。

// App is calling the HomePage and passing those data as props
<HomePage
    successMsg="App initialized"
    loadingMsg="Loading app…"
    errorMsg="Error encountered"
    serverDownMsg="Server down, Try again later!"
/>

// HomePage is calling SideBar and passing its props along
<SideBar
    successMsg={this.props.successMsg}
    loadingMsg={this.props.loadingMsg}
    errorMsg={this.props.errorMsg}
    serverDownMsg={this.props.serverDownMsg}
/>

// SideBar is calling StatusComponent and passing its props along
<StatusComponent    
    successMsg={this.props.successMsg}
    loadingMsg={this.props.loadingMsg}
    errorMsg={this.props.errorMsg}
    serverDownMsg={this.props.serverDownMsg}
/>

// Finally, StatusComponent is using the data passed all the way from App
switch(state) {
    case normal : return <p{this.props.successMsg}/>
    case loading : return <p{this.props.loadingMsg}/>
    case error : return <p{this.props.errorMsg}/>
    case serverDown : return <p{this.props.serverDownMsg}/>
}
Enter fullscreen mode Exit fullscreen mode

这很简单也很直接。👍 但是,如果在整个组件树中都使用这种方法,后果可能非常严重。👎 你会不断地在树中传递数据。你的组件会很快变得过于庞大。代码也会重复。(天哪!😠)

我们该怎么办?如何优化这段代码?让我们先来分析一下上面的代码!🧐 这里有两个因素在起作用:

  1. 存储数据的变量数量(在本例中为 4 个)
  2. 数据需要经过的组件数量,这里只有两个。应用程序拥有数据,状态组件正在使用数据。剩下的就是主页侧边栏了

我手头有两种策略🔥🔥。每种策略都将针对其中一个因素。

将它们分组为变量:

我们先来解决第一个因素,即包含数据的变量数量。

这是 JavaScript!我们可以简单地将这 4 个变量合并成一个。不过,不要合并任何变量。尽量只合并逻辑上相关的变量。幸运的是,在我们的例子中,这 4 个变量都是相关的。

// App is calling the HomePage and passing those grouped variables as props
<HomePage
    messages= {
        successMsg:"App initialized",
        loadingMsg:"Loading app…",
        errorMsg:"Error encountered",
        serverDownMsg:"Server down, Try again later!"
    }
/>

// HomePage is calling SideBar and passing its props along
<SideBar
    messages={this.props.messages}
/>

// SideBar is calling StatusComponent and passing its props along
<StatusComponent
    messages={this.props.messages}
/>

// Finally, StatusComponent is dividing the grouped variable passed all the way from App
switch(state) {
    case(success)    : return <p>{this.props.messages.successMsg}</p>
    case(loading)    : return <p>{this.props.messages.loadingText}</p>
    case(error)      : return <p>{this.props.messages.errorText}</p>
    case(serverDown) : return <p>{this.props.messages.serverDownText}</p> 
}
Enter fullscreen mode Exit fullscreen mode

这样看起来好多了,不是吗?今天可以结束了吗?

不!不过,这里还是有可以优化的地方!你看出来了?首页和侧边栏其实并不需要这些数据。它们只是充当数据传递的桥梁。我闻到了代码重复的味道🧐😠。但是我们不能直接删除它。或者,我们可以吗?😈

使用 React Context:

我们来探讨第二个因素,即数据需要经过决策树的层数。这里我们需要一些背景信息。

根据 React 文档,Context提供了一种在组件树中传递数据的方法,无需在每一层手动传递 props。这非常适合传递全局数据,例如语言环境偏好和 UI 主题,因为这些数据会被应用程序中的多个组件使用。

想看个例子吗?当然!

// First we create a context
const MessageContext = React.createContext({
    successMsg:"App initialized",
    loadingMsg:"Loading app…",
    errorMsg:"Error encountered",
    serverDownMsg:"Server down, Try again later!"
});

// App render method
<MessageContext.Provider>
    <HomePage />
</MessageContext.Provider>

// HomePage is calling SideBar without passing props
<SideBar/>

// SideBar is calling StatusComponent without passing props
<StatusComponent/>

// StatusComponent receiving its required data from the context instead of its parent
static contextType = MessageContext;
render() {
    switch(state) {
        case(success)    : return <p>{this.context.successMsg}</p>
        case(loading)    : return <p>{this.context.loadingText}</p>
        case(error)      : return <p>{this.context.errorText}</p>
        case(serverDown) : return <p>{this.context.serverDownText}</p> 
    }
}
Enter fullscreen mode Exit fullscreen mode

如上面的代码所示,我们没有将数据作为 props 传递。通过使用 context,我们无需关心组件树的层级有多深。context 中的数据可以从组件树中的任何位置访问。

您可以在React context 文档页面中找到更多详细信息。

您觉得这篇文章有用吗?
您是否已经了解这些内容?
请在下方评论区留言告诉我。

与往常一样,
快乐编码 🔥🔥
“ك٣ ك٣٣٠”

文章来源:https://dev.to/bassemibrahim/pass-data-through-react-s-tree-like-a-boss-2fbi