react項目如何操做dom

平時在作react項目過程當中不免會遇到一些特殊場景須要去操做DOM完成,好比錨點,這篇文章會從兩個角度(類組件、函數組件)去總結一些常見操做DOM的方式方法。react

一、父組件操做子組件DOM——React.forwardRef

在16.3版本以前,沒有辦法將ref傳遞到一個函數組件之中,可是隻要名字不相同是能夠經過props傳遞到子組件。git

偉大的fb在react 16.3中新加了一個React.forwardRef函數,使之子組件能夠直接接收refgithub

function forwardRef<T, P = {}>(render: ForwardRefRenderFunction<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;

interface ForwardRefRenderFunction<T, P = {}> {
    (props: PropsWithChildren<P>, ref: ForwardedRef<T>): ReactElement | null;
    displayName?: string;
    // explicit rejected with `never` required due to
    // https://github.com/microsoft/TypeScript/issues/36826
    /**
     * defaultProps are not supported on render functions
     */
    defaultProps?: never;
    /**
     * propTypes are not supported on render functions
     */
    propTypes?: never;
}

其實,React.forwardRef就是一個HOC,接收一個函數組件,這個函數組件能夠接收ref參數,說白了,React.forwardRef的做用就是能夠使被包裹組件接收ref參數。數組

這裏須要注意,泛型類型T指ref的類型,P指props類型。函數

下面舉個例子說明下用法:字體

// 父組件
const Father = () => {
    const ref = React.createRef<HTMLDivElement>();
    
    useEffect(() => {
        if (ref.current) {
            ref.current.style.fontSize = '16px';
        }
    })
    
    return <Child ref={ref}></Child>
}

// 子組件
const Child = React.forwardRef<HTMLDivElement, any>((props, ref) => {
    return <div ref={ref}>child</div>
})

在頁面初始渲染完後會修改Child組件中div文本字體大小。ui

二、組件內操做DOM——ref

// React.RefObject<HTMLInputElement>
import React, { useEffect } from 'react';

const InputFocus = () => {

  const inputRef = React.createRef<HTMLInputElement>();

  useEffect(() => {
    if (inputRef.current) {
      inputRef.current.focus();
    }
  })

  return <input type="text" ref={inputRef}/>
}

export default InputFocus;

或者this

// ((instance: HTMLInputElement | null) => void)
import React, { useEffect } from 'react';

const InputFocus = () => {

  let inputRef: HTMLDivElement | null = null;

  useEffect(() => {
    if (inputRef) {
      inputRef.focus();
    }
  })

  return <input type="text" ref={(el) => inputRef = el}/>
}

export default InputFocus;

若是在類組件內能夠以下寫:spa

// React.RefObject<HTMLInputElement>
class InputFocus extends React.Component<{}, {}> {
  inputRef = React.createRef<HTMLInputElement>();

  componentDidMount(){
    if (this.inputRef.current) {
      this.inputRef.current.focus()
    }
  }

  render() {
    return <input type="text" ref={this.inputRef}/>
  }
}

export default InputFocus;

或者code

// ((instance: HTMLInputElement | null) => void)
class InputFocus extends React.Component<{}, {}> {
  inputRef: HTMLInputElement | null = null;

  componentDidMount(){
    if (this.inputRef) {
      this.inputRef.focus()
    }
  }

  render() {
    return <input type="text" ref={(el) => this.inputRef = el}/>
  }
}

export default InputFocus;

image.png

這裏說明一下上面兩種使用方式,從上圖能夠得知ref能夠接收上面五種類型,能夠接收React.createRef建立的React.RefObject<HTMLInputElement>對象,也能夠接收一個函數,參數爲綁定該ref的元素。

三、

相關文章
相關標籤/搜索