返回

React 16.8 中父组件获取子组件数据的三种方法

见解分享

引言:

React 16.8 引入了对 hooks 的支持,这极大地改变了 React 组件的编写方式。其中一个最重要的变化是,现在父组件可以轻松地从其子组件中获取数据。本文将探讨三种不同的方法来实现这一目标,并重点介绍 React 16.8 中新引入的 hook,useRef。

一、类组件的情况

1. 直接使用 ref

在类组件中,最简单的方法是直接使用 ref。ref 是一个特殊属性,它允许父组件存储子组件的引用。要使用此方法,请在父组件中创建 ref,然后将其传递给子组件。在子组件中,可以使用 this.props.ref 来获取该引用。

// 父组件
class Parent extends React.Component {
  render() {
    return <Child ref={this.childRef} />;
  }

  childRef = (child) => {
    this.child = child;
  };
}

// 子组件
class Child extends React.Component {
  render() {
    return <div>子组件内容</div>;
  }
}

2. 子组件中

另一种方法是在子组件中使用 this.props.parentCallback。这要求父组件定义一个回调函数,并将其作为 prop 传递给子组件。子组件随后可以使用 this.props.parentCallback 将数据传递回父组件。

// 父组件
class Parent extends React.Component {
  render() {
    return (
      <Child
        parentCallback={(data) => {
          // 使用数据
        }}
      />
    );
  }
}

// 子组件
class Child extends React.Component {
  render() {
    return <div>子组件内容</div>;
  }

  componentDidMount() {
    // 获取数据并调用父组件的回调函数
    const data = ...;
    this.props.parentCallback(data);
  }
}

二、函数组件

1. 父组件

对于函数组件,可以使用 useRef hook 来获取子组件的引用。useRef hook 返回一个对象,其中包含一个 current 属性,该属性最初设置为 undefined。当将 ref 对象传递给子组件时,current 属性将更新为子组件的引用。

// 父组件
const Parent = () => {
  const childRef = useRef(null);

  return <Child ref={childRef} />;
};

// 子组件
const Child = ({ forwardedRef }) => {
  useImperativeHandle(forwardedRef, () => ({
    // 返回公开的 API
  }));

  return <div>子组件内容</div>;
};

2. 子组件中

与类组件类似,也可以在子组件中使用回调函数来传递数据。但是,函数组件不使用 this 上下文,因此必须使用 forwardedRef 参数来访问父组件的 ref 对象。

// 父组件
const Parent = () => {
  const [data, setData] = useState(null);

  return (
    <Child
      parentCallback={(newData) => {
        setData(newData);
      }}
    />
  );
};

// 子组件
const Child = ({ parentCallback }) => {
  const getData = () => {
    // 获取数据并调用父组件的回调函数
    const data = ...;
    parentCallback(data);
  };

  useEffect(() => {
    getData();
  }, []);

  return <div>子组件内容</div>;
};

三、优化

1. 子组件的代码

在大多数情况下,使用函数组件和 useRef hook 是获取子组件数据的最有效方法。这主要是由于函数组件的轻量级和 hooks 的声明式特性。

2. 父组件的代码

在父组件中,使用 useCallback hook 来优化回调函数。 useCallback hook 返回一个已记忆的函数,该函数在每次渲染时都不会重新创建。这可以提高性能,特别是当回调函数依赖于父组件状态时。

// 父组件
const Parent = () => {
  const [data, setData] = useState(null);
  const parentCallback = useCallback((newData) => {
    setData(newData);
  }, [data]);

  return <Child parentCallback={parentCallback} />;
};

结论:

React 16.8 引入了多种灵活的方法来让父组件从子组件中获取数据。类组件中的直接 ref 和子组件中的回调函数仍然有效,而 useRef hook 的引入为函数组件提供了轻量级且高效的解决方案。通过仔细考虑应用程序的特定需求,可以选择最适合的方法来促进组件之间的通信。