GGbond : react的通信方式

React组件间通信常见的几种情况:

  • 父组件向子组件通信
  • 子组件向父组件通信
  • 跨级组件通信
  • 非嵌套关系的组件通信

1. 父子组件的通信方式?

父组件向子组件通信:父组件通过 props 向子组件传递需要的信息。

// 子组件: Child
const Child = props =>{
  return <p>{props.name}</p>
}
// 父组件 Parent
const Parent = ()=>{
    return <Child name="react"></Child>
}

子组件向父组件通信:: props + 回调的方式。 具体来说,父组件可以将一个函数作为props传递给子组件,子组件在需要向父组件通信时,调用该函数并传递相应的数据作为参数。

// 父组件
function ParentComponent() {
  function handleChildClick(data) {
    console.log(`Received data from child component: ${data}`);
  }

  return (
    <div>
      <ChildComponent onClick={handleChildClick} />
    </div>
  );
}

// 子组件
function ChildComponent(props) {
  function handleClick() {
    const data = 'some data';
    props.onClick(data);
  }

  return <button onClick={handleClick}>Click me</button>;
}

在上面的代码中,父组件定义了一个名为handleChildClick的函数,并将其作为onClickprop传递给子组件。子组件在按钮被点击时调用handleClick方法,并传递一个字符串'some data'作为参数,该参数会被传递到父组件中的handleChildClick函数中,并在控制台中打印出来。这样就完成了子组件向父组件的通信。

2. 跨级组件的通信方式?

父组件向子组件的子组件通信,向更深层子组件通信:

  • 使用 props,利用中间组件层层传递,但是如果父组件结构较深,那么中间每一层组件都要去传递props,增加了复杂度,并且这些 props 并不是中间组件自己需要的。
  • 使用 context,context 相当于一个大容器,可以把要通信的内容放在这个容器中,这样不管嵌套多深,都可以随意取用,对于跨越多层的全局数据可以使用 context 实现。

创建一个名为UserContext的新上下文对象,并向其添加一个方法来更新用户信息:

import React, { createContext, useState } from 'react';

export const UserContext = createContext();

export const UserProvider = ({ children }) => {
  const [user, setUser] = useState({
    name: '',
    email: '',
    loggedIn: false,
  });

  const updateUser = (name, email) => {
    setUser(prevState => ({
      ...prevState,
      name,
      email,
      loggedIn: true,
    }));
  };

  return (
    <UserContext.Provider value={{ user, updateUser }}>
      {children}
    </UserContext.Provider>
  );
};

在这里,我们使用useState hook创建了一个名为user的状态,它包含用户名、电子邮件和登录状态。然后,我们定义了一个名为updateUser的函数,它可以用于更新用户信息。

最后,我们使用createContext函数创建了一个名为UserContext的新上下文对象,并使用UserProvider组件将其提供给所有子组件。我们还将user和updateUser方法作为值传递给该提供程序组件。

现在,我们可以在任何组件中使用Consumer组件来访问该上下文:

使用useContext hook从UserContext中获取值,并将其解构为user和updateUser方法。
然后,我们可以使用它们来显示用户信息并更新用户信息。

import React, { useContext } from 'react';
import { UserContext } from './UserContext';

export const Profile = () => {
  const { user, updateUser } = useContext(UserContext);

  const handleUpdateUser = () => {
    updateUser('John Doe', 'johndoe@gmail.com');
  };

  return (
    <div>
      <h2>User Profile</h2>
      <p>Name: {user.name}</p>
      <p>Email: {user.email}</p>
      <button onClick={handleUpdateUser}>Update User</button>
    </div>
  );
};

3. 非嵌套关系组件的通信方式?

即没有任何包含关系的组件,包括兄弟组件以及不在同一个父级中的非兄弟组件。

  • 可以使用自定义事件通信(发布订阅模式 event
  • 可以通过 redux 等进行全局状态管理
  • 如果是兄弟组件通信,可以找到这两个兄弟节点共同的父节点, 结合父子间通信方式进行通信。

4. 如何解决 props 层级过深的问题

  • 使用Context API:提供一种组件之间的状态共享,而不必通过显式组件树逐层传递props;
  • 使用Redux等状态库

5. 组件通信的方式有哪些

  • ⽗组件向⼦组件通讯: ⽗组件可以向⼦组件通过传 props 的⽅式,向⼦组件进⾏通讯
  • ⼦组件向⽗组件通讯: props + 回调的⽅式,⽗组件向⼦组件传递props进⾏通讯,此 props 为作⽤域为⽗组件⾃身的函 数,⼦组件调⽤该函数,将⼦组件想要传递的信息,作为参数,传递到⽗组件的作⽤域中
  • 兄弟组件通信: 找到这两个兄弟节点共同的⽗节点,结合上⾯两种⽅式由⽗节点转发信息进⾏通信
  • 跨层级通信: Context 设计⽬的是为了共享那些对于⼀个组件树⽽⾔是“全局”的数据,例如当前认证的⽤户、主题或⾸选语⾔,对于跨越多层的全局数据通过 Context 通信再适合不过
  • 发布订阅模式: 发布者发布事件,订阅者监听事件并做出反应,我们可以通过引⼊ event 模块进⾏通信
  • 全局状态管理⼯具: 借助 Redux 或者 Mobx 等全局状态管理⼯具进⾏通信,这种⼯具会维护⼀个全局状态中⼼ Store, 并根据不同的事件产⽣新的状态