React 16.8 中父组件获取子组件数据的三种方法
2024-02-05 20:57:26
引言:
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 的引入为函数组件提供了轻量级且高效的解决方案。通过仔细考虑应用程序的特定需求,可以选择最适合的方法来促进组件之间的通信。