React的兄弟组件传值-Refs JS与TS中的使用

什么是Refs

Refs provide a way to access DOM nodes or React elements created in the render method.
Refs提供了一种在React中访问Dom节点的方式

Refs转发

Ref 转发允许某些组件 接收 ref,并将其向下传递(换句话说,“转发”它)给子组件。
ref会在componentDidMount或者componentDidUpdate生命周期触发前更新。

当组件挂载componentDidMount时,React会将dom节点赋值给current,而当componentDidUpdate时,current的值被修改为null;

背景

在React单向数据流中,props是父子组件交互的唯一方式。
有些情况下,需要在数据流之外强行修改子组件(组件或者Dom元素),那么可以通过Refs来进行修改子组件。

访问 Refs

ref 的值根据节点的类型而有所不同:

  • 当 ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其current 属性。
  • 当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性。
  • 不能在函数组件上使用Ref属性,因为函数组件没有实例。但是当你在函数组件内部时,可以通过ref来访问Dom节点或class组件。

创建 Refs

例子

  1. 当 ref 属性用于 HTML 元素时,JS 使用 React.createRef() 创建Refs

    class MyComponent extends Component {
      private myRef = createRef()
      render() {
        return <div ref={this.myRef} />
      }
    }
    
  2. TS ts在jsx文件中有着非常优秀的类型推断,我们在一个<div>上增加了ref <div ref={this.myRef} />,ts就推断出需要使用HTMLDivElement类型进行接收.
    由于 React.createRef的定义function createRef<T>(): RefObject<T> 返回的RefObject是泛型;
    解决方法:createRef<HTML自定义Element>()

    import React from "react";
    import { Component, createRef } from "react";
    
    export default class TextInput extends React.Component {
      
        componentDidMount(){
            console.log(this.textInput, 'chloe')
        }
        private textInput = createRef<HTMLInputElement>()
        textInputFocus = () => {
            //我们通过“current”来访问dom节点
            this.textInput.current?.focus();
            console.log(this.textInput.current, 'chloe')
        }
        render(){
            return(
                <div>
                    <input type="text" ref={this.textInput} />
                    <input type="button" value="focus this Input" onClick={this.textInputFocus} />
                </div>
            )
        }
    }
    

    在这里插入图片描述
    我们可以直接通过定义在ref上的current属性来访问这个node 节点
    React文档是这样定义current的:

    当组件挂载componentDidMount时,React会将dom节点赋值给current,而当componentDidUpdate时,current的值被修改为null;

使用Refs实现兄弟组件传值

例子:TS 自定义Class组件 添加Ref

<DefalutLayout/> 父组件 包含两个子组件 HeaderPage和 IndexPage
现在要点击 <Headerpage/>中的一个 图片按钮Button, 在<IndexPage/>中 显示一个tips (提示页面)<TipsPage />

  1. <IndexPage/> 定义显示tips的方法 showTip()
  2. 父组件 <DefalutLayout/>通过refs获取子组件<IndexPage/>的showTip()
  3. 父组件 <DefalutLayout/>将showTip() 传给另一个子组件 <Headerpage/>
import React, {createRef} from 'react';

import { PageHeader } from '../../components/HeaderPage';
import SpeechRetrieval from '../speechRetrieval/IndexPage';

export default class DefalutLayout extends React.Component {
  tipsBtn = createRef<IndexPage>()
  tips = () => {
  	//调用子组件
    this.tipsBtn.current?.showTip()
    };
  
  render() {
    return (
      <div id="container">
       <Layout>
                <HeaderPage tips={this.tips}/>
                <IndexPage ref={this.tipsBtn}></IndexPage>
        </Layout> 
    </div>
    );

  }
}

子组件 IndexPage

//自定义子组件 IndexPage
export default class IndexPage extends React.Component {
	state = { tipVisible:false }
	//被调用方法
	showTip = () =>{
        this.setState({
            tipVisible:true
        })
    }
    render(){
    	const { tipVisible } = this.state;
    	return(
    		{ tipVisible && visible ? (<TipsPage />):(<p></p>) }
    	)
	}
}

子组件 HeaderPage

import React from 'react';
import { Layout, Popconfirm } from 'antd';
const { Header } = Layout;

export function HeaderPage(props) {
    return (
        <Header className="header">
            <div className="header-right-section">
                <div onClick = {() => {props.tips()}}>
                    <img className="header-right-icon" src='/icon/tips.png' alt="tips"/>
                </div>
            </div>
        </Header >
    );
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值