react useref的使用

大概分享一下两种常见情况下,使用useref。

第一种,同一组件内部,通过useref来获取某一个dom标签以及dom标签的方法。

在以前使用ref的时候,我们经常用ref来保存某个需要的dom标签,这样需要用到的时候,就可以不用去寻找这个dom标签了,在js中,通过方法,parentNode,lastchild,nextElementsibling 这种关系结构来找dom是一件比较麻烦的事情。如果不是动态类名或者id的话,通过document.getElementsByClassName 之类的方法,虽然可行,却也比较麻烦,因为得到的是一个dom数组。

看看useref如何实现

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

export default function App(props){
     
  const [count, setCount] = useState(0);

  const doubleCount = useMemo(() => {
     
    return 2 * count;
  }, [count]);

  const couterRef = useRef(); //创建useRef

  useEffect(() => {
     
    document.title = `The value is ${
     count}`;
    //通过couterRef 的current 属性可以获取到button这个dom
    console.log(couterRef.current);
  }, [count]);
  
  return (
    <>
    //与ref类似,绑定到button标签上
      <button ref={
     couterRef} onClick={
     () => {
     setCount(count + 1)}}>Count: {
     count}, double: {
     doubleCount}</button>
    </>
  );
}

第二种,跨组件获取子组件的方法。

在以往的ref中,可以将ref绑定到某个子组件标签上,用以获取整个子组件的方法和参数,在react 的useref也有类似的功能。

父组件代码

import React, {
      useRef } from 'react';
import StudentStatusForm from './components/student-status-info-emdit//student-status-info-emdit';

const StudentBase: React.FC = (props) => {
     

  const onClickConfirmStudentStatusInfo = () => {
     
  	//获取StudentStatusForm 子组件onFinish方法
    userInfoStatus.current
      .onFinish()
      .validateFields()
      .then(() => {
     
        setStudentInfoStatus(0);
      });
  };

	const userInfoStatus = useRef();
	return (
		<>	
			//当点击Button的时候获取StudentStatusForm 子组件的onFinish方法
			<Button onClick={
     onClickConfirmStudentStatusInfo }>获取onFinish方法</Button>
			<StudentStatusForm ref={
     userInfoStatus} initialValues={
     studentDetailsData} />
		</>
)


}

export default StudentBase;

子组件代码

import React, {
      useState, useEffect, forwardRef, useImperativeHandle } from 'react';
import {
     Form} from 'antd';

//子组件不再使用react的React方式来创建,直接通过函数的方式创建,函数子组件接收两个参数,第一个参数是父组件传过来的其它参数,第二个参数是ref
const StudentStatusForm = (props: StudentStatusFormType, ref: any) => {
     
  const {
      initialValues } = props;
  const [form] = Form.useForm();

  const onFinish = () => {
     
    return form;
  };
  
  useEffect(() => {
     
    const newInitialValues = {
     ...initialValues}
    newInitialValues.admissionDate = moment(initialValues.admissionDate);
    newInitialValues.birthday = moment(initialValues.birthday);
    form.setFieldsValue(newInitialValues);
  }, [initialValues]);

//react规定,必须使用useImperativeHandle方法,来保存并抛出想要传递给父组件的方法或者数据,第一个参数是ref,第二个参数是函数,返回想要抛出的对象集合
  useImperativeHandle(ref, () => ({
     
    onFinish,
  }));

  return (
    <div className="student-status-info-emdit">
      <Form {
     ...formItemLayout} form={
     form}>
        
      </Form>
    </div>
  );
};

//必须通过forwardRef方法抛出函数组件
export default forwardRef(StudentStatusForm);

不常用却好用的useref骚操作
在react中,无论是使用usestate来保存数据,如果这数据被修改,将会引起页面的重新渲染。

可有时候,我们想要保存的数据不大,但当数据改变的时候不想页面重新渲染,这份数据在页面多次重新渲染后仍然能保持不变。

要做到以上条件使用什么方法呢?
1 reducer 感觉多少还是有些麻烦,
2 保存到浏览器locationstoreage,取的时候也麻烦,不安全。
3 保存到服务器,可能你会被骂死,这么一点小数据还要麻烦后端。
4 保存到useref里面去。

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

export default function App(props){
     
  const [count, setCount] = useState(0);

  const doubleCount = useMemo(() => {
     
    return 2 * count;
  }, [count]);

// 创建useRef
  const timerID = useRef();
  
  useEffect(() => {
     
  // 不从useRef取值,而是赋值给它,用来保存定时器格外酸爽
    timerID.current = setInterval(()=>{
     
        setCount(count => count + 1);
    }, 1000); 
  }, []);
  
  useEffect(()=>{
     
      if(count > 10){
     
      	// 当你需要使用的时候,依然存在,停掉定时器,
          clearInterval(timerID.current);
      }
  });
  
  return (
    <>
    //绑定ref
      <button ref={
     couterRef} onClick={
     () => {
     setCount(count + 1)}}>Count: {
     count}, double: {
     doubleCount}</button>
    </>
  );
}

上面代码不是我写的,来自一位大神的博客,偶然发现,与大家分享一下。
https://blog.csdn.net/hjc256/article/details/102587037

你可能感兴趣的:(react框架逻辑,react,useref)