在 React 父子组件、非父子组件间传递数据

React 是 Facebook 创造的 JavaScript 库。虽然在 React 中处理数据显得有点复杂,但其实并没有那么棘手。最近我总结了三种在 React 中进行数据处理的方法:

  1. 使用 Props 从父组件传递数据到子组件
  2. 使用回调函数从子组件传递数据到父组件
  3. 非父子组件之间传递数据:
    • 结合 Props 和回调函数
    • 使用 Redux 传递数据
    • 使用 React Context API 传递数据

这篇文章中主要总结了这些实现方式,新手可以从中纵览全局。

使用 Props 从父组件传递数据到子组件

假设我们的目录结构如下所示:

App
└── Parent
    ├── Child1
    └── Child2

这是 React 中最简单也是最基础的数据流向。

class Parent extends React.Component {
    state = { data : "Hello World" } 
    render() {
        return (
            <div>
                 <Child1/> // 无数据传递           
                 <Child2 dataFromParent = {this.state.data} />
            </div>
        );
    }
}
// 没有强制要求必须传递 state 中的值,通过 var 或者 const 定义的变量也可以从父组件传递给子组件

在子组件中,可以非常简单地使用 this.props.dataFromParent (只是一个通过 props 传递的变量) 来获取到从父组件传递过来的数据。

class Child2 extends React.Component {
    render() {
        return (
            <div>
                The data from parent is:{this.props.dataFromParent}
            </div>
        );
    }
}

使用回调函数从子组件传递数据给父组件

如果我要从 Child1 子组件中传递信息——“美女,最近还好吗?” 给父组件,应该怎么做呢?为了实现这个目的,需要按照以下步骤进行操作:

第一步:在父组件中定义一个有参数的回调函数

第二步:将该回调函数作为 Props 传递到 Child1 子组件

class Parent extends React.Component {
    state = { message: "" }
    callbackFunction = (childData) => {
      this.setState({message: childData})
    },
    render() {
        return (
            <div>
                 <Child1 parentCallback = {this.callbackFunction}/>
                 <p> {this.state.message} </p>
            </div>
        );
    }
}

第三步:在子组件中,通过调用 this.props.callback(dataToParent) 将数据 dataToParent 传递给父组件

class Child1 extends React.Component{
    sendData = () => {
         this.props.parentCallback("美女,最近还好吗?");
    },
    render() { 
        //在想传递信息给父组件的任意时刻调用 sendData 方法
    }
};

非父子组件之间传递数据

当我还是一个初学者的时候,选择哪种方式进行非父子组件间通讯对我来说是一个难题。现在我知道有以下三种方式,并且每种方式都有自己的优缺点。

方式1:结合 Props 和回调函数

这种方式不适用复杂的组件树,因为这将有一大部分进行数据传递的代码要写,而且需要中间层进行数据的传递,虽然可能它们并不需要该数据。

方式2:使用 Redux 传递数据

方式3:使用 React Context API 传递数据

现在有很多关于为什么 React 增强了 Context API 以及在何场景下哪种方式更优的文章。以下是两篇推荐:

React Context API — A Replacement for Redux?

You Might Not Need Redux

我使用过这种方式,相比 Redux,我更倾向于使用该方式。

Context API 的最大优势是:这种方式使开发者从 “Prop 深渊”中解放出来。(Props 深渊是指传递数据到子组件中。主要的思路是函数式编程,不断地将参数传递给下一个函数)

建设我们有以下的组件树,想要从 Child1 中传递信息“SSup brother?”给组件 Child2。

App
├── Child1
└── Child2

第一步:为两个子组件创建一个 Provider

这个 Provider 管理 state 并返回一个 contextObject.Provider 组件。

第二步:在 Provider 组件中,使用 props 传递 state 和回调函数

export const MContext = React.createContext(); 
// 导出 context 对象
class MyProvider extends Component {
    state = {message: ""}
    render() {
        return (
            <MContext.Provider value={
                {
                    state: this.state,
                    setMessage: (value) => this.setState({message: value })}}>
            {this.props.children}   // 这里显示所有的子组件都可以访问全局的 store
            </MContext.Provider>)
    }
}

provider 是所有子组件共享的(一个全局的store,保存了所有 state 和一个操作这些 state 的回调函数)。任何需要这些状态的组件都需要先和 provider 打交道。

(a) 在 Child1 中通过 provider 中的 setMessage 处理信息

(b) 在 Child2 中通过 provider 获取信息

第三步:将 MyProvider 当做 Child1 和 Child2 两个组件的父组件

class App extends React.Component {
    render() {
        return (
            <div>
                 <MyProvider>
                      <div className="App">
                      <Child1/>
                      <Child2/>
                      </div>
               </MyProvider>
            </div>
        );
    }
}

第四步:Child1 和 Child2 都是 Provider 的消费者,进而都需要通过使用 Consumer 标签来与 Provider 打交道。

import MContext
class Child1 extends React.Component {
    render() {
        return (
            <div>
                <Mcontext.Consumer>
                    {(context) => (
                        <button onClick={()=>{context.setMessage("New Arrival")}}>Send</button>
                    )}
                </Mcontext.Consumer>
            </div>
        )
    }
}

Child2 中如何接收这些数据呢?

也是用 Consumer 标签与 Provider 打交道。

import MContext
class Child2 extends React.Component {
    render() {
       return (
         <div>
            <Mcontext.Consumer>
                {(context) => (
                    <p>{context.state.message}}</p>
                )}
            </Mcontext.Consumer>
         </div>
        )
    }
}

希望上面的描述比较清晰的解释了如何在 React 中进行大量组件的数据传递。

推荐阅读:

Using Context in React

猜你喜欢

转载自www.cnblogs.com/indeeds/p/11717422.html