React Context API,从子组件设置上下文状态,而不是将函数作为道具传递

Posted

技术标签:

【中文标题】React Context API,从子组件设置上下文状态,而不是将函数作为道具传递【英文标题】:React Context API, set context state from Child Components instead of passing functions as props 【发布时间】:2019-10-05 16:54:56 【问题描述】:

React 文档说,如果您打算从嵌套组件更新上下文,则将根组件中定义的函数作为道具传递给子组件。

我已经实现了相同的:

import React from 'react';

const DataContext = React.createContext();

/**
 * The App.
 */
export default class App extends React.Component 
    constructor() 
        super();

        this.updateGreet = this.updateGreet.bind( this );

        this.state = 
            greet: '',
            updateGreet: this.updateGreet
        
    

    updateGreet() 
        this.setState(
            greet: 'Hello, User',
        );
    

    render() 
        return (
            <DataContext.Provider value= this.state >
                <GreetButton />
                <DisplayBox />
            </DataContext.Provider>
        )
    


/**
 * Just a button element. On clicking it sets the state of `greet` variable.
 */
const GreetButton = () => 
    return (
        <DataContext.Consumer>
            
                (  updateGreet  ) => 
                    return <button onClick= updateGreet >Greet</button>
                
            
        </DataContext.Consumer>
    )


/**
 * Prints the value of `greet` variable between <h1> tags.
 */
const DisplayBox = () => 
    return (
        <DataContext.Consumer>
            
                (  greet  ) => 
                    return <h1> greet </h1>
                
            
        </DataContext.Consumer>
    )

这是我为学习 Context API 而创建的一个非常简单的 React 应用程序。我想要实现的是在GreetButton 组件中定义updateGreet() 方法,而不是在App 组件中定义它,因为该函数与App 组件无关。

我看到的另一个优点是,如果我选择完全删除 GreetButton 组件,那么我不需要跟踪它在另一个组件中定义的所有方法。

有什么方法可以实现吗?

【问题讨论】:

您可以传递setState 并在任何地方定义方法(哇——您可以随时扩展可能性)...但您可能不知道上下文的用途。 【参考方案1】:

我认为updateGreet 方法确实App 有关,因为它正在操纵App 状态。

我不认为这是一个特定于上下文的问题,而是将函数向下传递给子组件的正常反应实践。

为了实现您的愿望,您可以绑定AppsetState 方法并将其传递给提供程序,然后在GreetButton 组件中实现updateGreet,但这将是一个反模式,我不会推荐它。

当我使用 Context API 时,我通常在一个单独的文件中定义我的上下文,并实现一个自定义提供程序以满足我的需要,向下传递相关的方法和属性,并根据需要在整个树中使用它们。

基本上,将App 中的内容实现为它自己的ProviderGreetProvider。在GreetProvider 的渲染方法中,只需将孩子传递给:

render() 
        return (
            <DataContext.Provider value= this.state >
                 this.props.children 
            </DataContext.Provider>
        )
    

现在,您的所有问候语逻辑都可以在源头与上下文一起存在。在App 中使用新的GreetProvider 类,它的任何子级都可以使用它的方法。

【讨论】:

以上是关于React Context API,从子组件设置上下文状态,而不是将函数作为道具传递的主要内容,如果未能解决你的问题,请参考以下文章

React Context API和组件方法[重复]

React Hook:将数据从子组件发送到父组件

在 React Native 中将状态从子组件传递到父组件

NextJS 使用带有布局组件包装器的 React 的 Context API

React Context API似乎重新渲染每个组件

React Context API 似乎要重新渲染每个组件