React基础 - refs的详解与应用

ref的使用场景

React核心就在于虚拟DOM,也就是在React中不总是直接操作页面真实的DOM元素,并且结合Diffing算法,可以做到最小化页面重绘。

但有些时候不可避免的我们需要一种方法可以操作我们定义的元素标签,并作出对应的修改。在React中提供了一种访问DOM节点的方式,也就是这里的refs

refs 的使用场景:

  • 管理焦点,文本选择或媒体播放。
  • 触发强制动画。
  • 集成第三方 DOM 库。

例子

import React from 'react';

export default function App() {
  return (
    <div>
      <RefsExample />
    </div>
  );
}

class RefsExample extends React.Component {
  constructor() {
    super();
    this.usernameRef = React.createRef();
    this.passwordRef = React.createRef();
  }

  handleSubmit = (e) => {
    let username = this.usernameRef.current.value;
    let password = this.passwordRef.current.value;
    if (!(username === '123' && password === '1')) {
      e.preventDefault();
      alert('信息不正确!');
    }
  };

  render() {
    return (
      <form action="" onSubmit={this.handleSubmit}>
        用户名:
        <input ref={this.usernameRef} type="text" />
        <br />
        密 码:
        <input ref={this.passwordRef} type="password" />
        <br />
        <button>提交</button>
      </form>
    );
  }
}

注意到,上面的代码中我们使用了React.createRef()来创建一个ref引用,继而可以直接使用这个引用来获取到用户输入的值。

操作原始DOM

class组件

1. React.createRef(推荐)

import React, { Component } from 'react';

export default function App() {
  return (
    <div>
      <RefsDemo1 />
    </div>
  );
}

class RefsDemo1 extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.inputRef = React.createRef();
  }
  componentWillMount() {
    console.log('componentWillMount->inputRef:', this.inputRef);
  }
  componentDidMount() {
    console.log('componentDidMount->inputRef:', this.inputRef);
    this.inputRef.current.focus();
  }
  render() {
    return (
      <div>
        姓名: <input ref={this.inputRef} />
      </div>
    );
  }
}

在这里插入图片描述

2. 回调函数方式

class RefsDemo2 extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.inputRef = null;
  }

  componentWillMount() {}
  componentDidMount() {
    this.inputRef.focus();
  }
  render() {
    return (
      <div>
        姓名:
        <input
          ref={(ref) => {
            this.inputRef = ref;
          }}
        />
      </div>
    );
  }
}

3. string 方式(不推荐)

class RefsDemo3 extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  componentWillMount() {
    console.log('componentWillMount->inputRef:', this.refs.inputRef);
  }
  componentDidMount() {
    console.log('componentDidMount->inputRef:', this.refs.inputRef);
    this.refs.inputRef.focus();
  }

  render() {
    return (
      <div>
        姓名:
        <input ref="inputRef" />
      </div>
    );
  }
}

function组件

因为 function 组件不存在 this,所以需要用到 React Hook

import React, { useRef, useEffect } from 'react';

export default function App() {
  return (
    <div>
      <RefsDemo4 />
    </div>
  );
}

function RefsDemo4() {
  const inputRef = useRef();

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return (
    <div>
      Function-Ref:
      <input ref={inputRef} />
    </div>
  );
}

操作 React 组件

class组件

父组件可以获取子组件实例并调用子组件中定义的方法。

import React, { Component, useRef, useEffect } from 'react';

export default function App() {
  return (
    <div>
      <ClassDemo />
    </div>
  );
}

class ClassDemo extends Component {
  onCheck = (type) => {
    alert('type: ' + type);
  };

  render() {
    return <div onClick={this.onCheck.bind(this, 'child')}>Class</div>;
  }
}

class RefDemo extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.classRef = React.classRef();
  }

  componentWillMount() {
    console.log('componentWillMount: ', this.classRef);
  }

  componentDidMount() {
    console.log('componentDidMount: ', this.classRef);
  }

  render() {
    return <ClassDemo ref={this.classRef} />;
  }
}

function 组件

函数组件不能使用ref属性,需要时可以使用React.forwardRef

import React, {
  Component,
  useImperativeHandle,
  useRef,
  useEffect,
} from 'react';

export default function App() {
  return (
    <div>
      <RefDemo />
    </div>
  );
}

const FunctionComponent = React.forwardRef(function Function(props, ref) {
  const onCheck = (type) => {
    alert('type: ' + type);
  };

  useImperativeHandle(ref, () => ({
    onCheck: onCheck.bind(null, 'father'),
  }));

  return <div onClick={onCheck.bind(null, 'child')}>Function</div>;
});

class RefDemo extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.functionRef = React.createRef();
  }

  componentWillMount() {
    console.log('componentWillMount: ', this.functionRef);
  }

  componentDidMount() {
    console.log('componentDidMount: ', this.functionRef);
  }

  render() {
    return (
      <div>
        <FunctionComponent ref={this.functionRef} />
        <button
          onClick={() => {
            this.functionRef.current.onCheck();
          }}
        >
          调用子组件方法
        </button>
      </div>
    );
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
React Native是一个用于构建跨平台移动应用的开源框架。它允许开发者使用JavaScriptReact的语法来编写移动应用,并且可以同时在iOS和Android平台上运行。 要打包React Native应用为iOS应用,可以按照以下步骤进行操作: 1. 配置Xcode环境:首先,确保你的电脑上已经安装了Xcode,并且已经配置好了iOS开发环境。 2. 创建React Native项目:使用React Native的命令行工具创建一个新的项目,可以通过运行以下命令来创建一个新的React Native项目: ``` npx react-native init MyApp ``` 3. 进入项目目录:进入到项目的根目录,可以使用以下命令进入项目目录: ``` cd MyApp ``` 4. 打开Xcode工程:使用Xcode打开iOS工程文件(.xcodeproj),可以通过运行以下命令来打开Xcode: ``` open ios/MyApp.xcodeproj ``` 5. 配置签名和证书:在Xcode中,选择你的项目,在"Signing & Capabilities"选项卡中配置你的开发者账号和证书。 6. 选择目标设备:在Xcode中,选择你要构建的目标设备,可以是模拟器或者真机。 7. 构建应用:点击Xcode中的"Build"按钮来构建应用,或者使用快捷键"Command + B"。 8. 运行应用:点击Xcode中的"Run"按钮来运行应用,或者使用快捷键"Command + R"。 以上是打包React Native应用为iOS应用的基本步骤。在实际开发中,可能还需要进行一些其他的配置和调整,例如添加依赖库、处理权限等。具体的操作可以参考React Native官方文档或者相关的教程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZhShy23

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值