这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战
写在前面:
本系列代码源码已经上传github,大家可以随意下载,后面会给上视频讲解辅助,帮助大家更加融会贯通!
源码地址:JACK-ZHANG-coming/react-demo-project: 用于存放一些react相关的基础例子; (github.com)
本文作为本人学习总结之用,同时分享给大家,如果觉得这些内容有对你也有用的话,就请点个赞吧~ 谢谢~
因为个人技术有限,如果有发现错误或存在疑问之处,欢迎指出或指点!不胜感谢!
个人前端博客网站:zhangqiang.hk.cn
欢迎加入博主的前端学习qq交流群:706947563,专注前端开发,共同学习进步!
本系列你将能学到:
- 父组件传值与函数给子组件,在子组件可使用父组件的值与函数; (该章链接:juejin.cn/post/699147…)
- 子组件传值与函数给父组件,在父组件里面可使用子组件里面的值与函数;(本章讲解)
- 子组件传值与函数给子组件,在子组件里面可使用另一个子组件的值与函数;
子组件传值与函数给父组件,在父组件可使用子组件的值与函数
- 通过react的hooks新特性,
useRef、useImperativeHandle、forwardRef来实现。
useRef :
useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内持续存在。
useImperativeHandle :
useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用 ref 这样的命令式代码。useImperativeHandle 应当与 forwardRef 一起使用。
forwardRef :
React.forwardRef 接受渲染函数作为参数。React 将使用 props 和 ref 作为参数来调用此函数。此函数应返回 React 节点。
父组件关键代码
import React, { useState, useRef, useEffect } from 'react';
import Child1 from './components/Child1/index';
import Child2 from './components/Child2/index';
const App = () => {
const [parentValue, setParentValue] = useState('我是父组件的值-');
const [isChild2value, setIsChild2value] = useState('');
const Child2Ref = useRef(null); // 给Child2一个ref,让外层的父组件可以调用子组件里面的函数
useEffect(() => {
setIsChild2value(Child2Ref?.current?.areGetChild2Value());
}, [])
return (
<div style={{ width: '60%', margin: '0 auto', textAlign: 'center', border: '3px solid red' }}>
<h2>我是父组件</h2>
<h4>{parentValue}</h4>
<button style={{ margin: '20px 0' }} onClick={() => { setParentValue('我触发父组件函数了,' + parentValue); }}>父组件按钮</button>
<div style={{ display: 'flex', justifyContent: 'center', alignContent: 'center', margin: '20px 0' }}>
<div style={{ display: 'flex', justifyContent: 'center', alignContent: 'center', width: '50%', margin: '0' }}>
<button
onClick={() => {
Child2Ref?.current?.areSetChild2Value();
setTimeout(() => {
setIsChild2value(Child2Ref?.current?.areGetChild2Value());
}, 100); // 延迟函数 因为useState是异步
}}
>
父组件调用子组件2函数
</button>
</div>
<div style={{ display: 'flex', justifyContent: 'center', alignContent: 'center', width: '50%', margin: '0' }}>
<p>父组件显示子组件2内容:{isChild2value}</p>
</div>
</div>
<Child1 parentValue={parentValue} setParentValue={setParentValue}></Child1>
<Child2 ref={Child2Ref}></Child2>
</div>
);
}
export default App;
子组件关键代码
import React, {
useState,
useImperativeHandle,
forwardRef
} from 'react';
const Child2 = (props, ref) => {
const [child2Value, setChild2Value] = useState('子组件2数值')
useImperativeHandle(ref, () => {
return {
child2Value, // 对象简写,全写为child2Value: child2Value,
areGetChild2Value: () => {
return child2Value
},
areSetChild2Value: () => {
setChild2Value(child2Value + '子组件2数值-变了!')
}
}
})
return (
<>
<div style={{ width: '60%', margin: '30px auto', padding: '30px 5px', textAlign: 'center', border: '3px solid yellowgreen' }} >
<h3>我是子组件2</h3>
<div>子组件使用父组件的值:{child2Value}</div>
<button style={{ margin: '20px 0' }} onClick={() => { setChild2Value(child2Value + '子组件2数值-变了!'); }}>子组件2内置按钮</button>
</div>
</>
)
}
export default forwardRef(Child2);
感谢看完!