今天本来正在工位上写着一段很普通的业务代码,将其简化后大致如下:
function App(props: any) {// 父组件const subRef = useRef<any>(null)const [forceUpdate, setForceUpdate] = useState<number>(0)const callRef = () => {subRef.current.sayName() // 调用子组件的方法}const refreshApp = () => { // 模拟父组件刷新的方法setForceUpdate(forceUpdate + 1)}return <div><SubCmp1 refreshApp={refreshApp} callRef={callRef} /><SubCmp2 ref={subRef} /></div>}class SubCmp1 extends React.Component<any, any> { // 子组件1constructor(props: any) {super(props)this.state = {count: 0}}add = () => {this.props.refreshApp()// 会导致父组件重渲染的操作// 修改自身数据,并在回调函数中调用外部方法this.setState({ count: this.state.count + 1 }, () => {this.props.callRef()})}render() {return <div><button onClick={this.add}>Add</button><span>{this.state.count}</span></div>}}const SubCmp2 = forwardRef((props: any, ref) => { // 子组件2useImperativeHandle(ref, () => {return {sayName: () => {console.log('SubCmp2')}}})return <div>SubCmp2</div>})
代码结构其实非常简单 , 一个父组件包含有两个子组件 。其中的组件2因为要在父组件中调用它的内部方法 , 所以用forwardRef
包裹,并通过useImperativeHandle
向外暴露方法 。组件1则是通过props传递了两个父组件的方法,一个是用于间接地访问组件2中的方法,另一个则是可能导致父组件重渲染的方法(当然这种结构的安排明显是不太合理的,但由于项目历史包袱的原因咱就先不考虑这个问题了\doge) 。
然后当我满心欢喜地
推荐阅读
- 装配 SpringBoot自动配置流程
- 如何把螃蟹杀掉(如何将螃蟹从洞里赶出来)
- 真我gtneo闪速版和普通版区别_哪款更值得入手
- C# RulesEngine 规则引擎:从入门到看懵
- C++算法之旅、02 从木棒切割问题领悟二分法精髓
- 3 Python全栈工程师之从网页搭建入门到Flask全栈项目实战 - 入门Flask微框架
- 机器学习实战-AdaBoost
- 从0搭建vue3组件库:自动化发布、管理版本号、生成 changelog、tag
- 三星zflip3韩版和国行的区别_哪款更值得入手
- 荣耀50和荣耀v40区别对比_哪款更值得入手