목차
react-hooks로 해결되는 문제
다음은 페이지에서 마우스 위치를 얻기 위한 로직 재사용의 예입니다.
훅이 사용되는 것을 명확하게 볼 수 있습니다. 로직을 재사용하는 것이 더 편리하고, 사용하면 로직이 더 명확해집니다.
각 프레임에는 독립된 상태가 있습니다
useEffect는 비동기식이며 구성요소 렌더링이 완료된 후 실행됩니다.
Syntax
4、useRef
5、useReducer
6、useContext
7、useLayoutEffect
웹 프론트엔드 프런트엔드 Q&A 반응 후크와 클래스의 차이점은 무엇입니까?

반응 후크와 클래스의 차이점은 무엇입니까?

Mar 22, 2022 pm 12:12 PM
class react hook

차이점: 1. 후크는 클래스보다 더 간결하게 작성됩니다. 2. 후크의 비즈니스 코드는 클래스보다 더 집계됩니다. 3. 클래스 구성 요소의 논리 재사용은 일반적으로 렌더링 소품과 HOC를 사용하는 반면, 반응 후크는 논리를 재사용하기 위한 사용자 정의 후크를 제공합니다. .

반응 후크와 클래스의 차이점은 무엇입니까?

이 튜토리얼의 운영 환경: Windows 7 시스템, 반응 버전 17.0.1, Dell G3 컴퓨터.

반응 후크와 클래스 구성 요소의 차이점은 무엇입니까? 반응 후크와 클래스 구성 요소를 비교하고 차이점에 대해 이야기해 보겠습니다.

react-hooks로 해결되는 문제

  • 함수 구성 요소는 자체 상태를 가질 수 없습니다. Hooks 이전에는 함수 구성 요소가 Stateless였으며 부모 구성 요소의 상태는 props를 통해 획득되었지만 Hook은 함수 구성 요소의 내부 상태를 유지하기 위해 useState를 제공합니다.

  • 기능 컴포넌트에서는 컴포넌트의 수명주기를 모니터링할 수 없습니다. useEffect는 여러 수명주기 함수를 집계합니다.

  • 클래스 구성 요소의 수명 주기는 더 복잡합니다(버전 15에서 버전 16으로 변경 사항이 큽니다).

  • 클래스 구성 요소 로직은 재사용하기 어렵습니다(HOC, 렌더링 소품). 클래스와 비교 한 후크의 비교 (비교)

1은 더 간결합니다.

훅을 사용한 코드가 클래스 컴포넌트 코드보다 더 간결하고 명확하다는 것을 알 수 있습니다.

2. 비즈니스 코드가 더 집계됩니다

클래스 구성 요소를 사용할 때 함수가 두 개의 수명 주기 함수에 나타나는 경우가 종종 있습니다. 예:

class ExampleOfClass extends Component {
  constructor(props) {
    super(props)
    this.state = {
      count: 1
    }
  }
  handleClick = () => {
    let { count } = this.state
    this.setState({
      count: count+1
    })
  }
  render() {
    const { count } = this.state
    return (
      <div>
        <p>you click { count }</p>
        <button onClick={this.handleClick}>点击</button>
      </div>
    )
  }
}
로그인 후 복사

타이머 추가와 타이머 지우기는 서로 다른 두 가지 수명주기 기능에 있기 때문에 그 사이에 다른 비즈니스 코드가 많이 있을 수 있으므로 타이머 지우기가 추가되지 않은 경우 타이머 지우기를 잊어버릴 수 있습니다. 구성 요소가 제거되면 서버 기능으로 인해 메모리 누수 및 지속적인 네트워크 요청 등의 문제가 발생할 수 있습니다. 그러나 후크를 사용하면 코드를 더 중앙 집중화하고 관리하기 쉽게 만들 수 있으며 잊어버리기 쉽지 않습니다.

function ExampleOfHooks() {
    const [count, setCount] = useState(0)
    const handleClick = () => {
        setCount(count + 1)
    }
    return (
      <div>
        <p>you click { count }</p>
        <button onClick={handleClick}>点击</button>
      </div>
    )
}
로그인 후 복사

3. 로직 재사용이 편리합니다.

클래스 구성 요소의 로직 재사용은 일반적으로 렌더링 소품과 HOC를 사용합니다. React Hooks는 로직을 재사용하기 위한 사용자 정의 후크를 제공합니다.

다음은 페이지에서 마우스 위치를 얻기 위한 로직 재사용의 예입니다.

클래스 컴포넌트 렌더링 소품 재사용

let timer = null
componentDidMount() {
    timer = setInterval(() => {
        // ...
    }, 1000)
}
// ...
componentWillUnmount() {
    if (timer) clearInterval(timer)
}
로그인 후 복사

custom Hooks 재사용

useEffect(() => {
    let timer = setInterval(() => {
        // ...
    }, 1000)
    return () => {
        if (timer) clearInterval(timer)
    }
}, [//...])
로그인 후 복사

훅이 사용되는 것을 명확하게 볼 수 있습니다. 로직을 재사용하는 것이 더 편리하고, 사용하면 로직이 더 명확해집니다.

hooks 일부 일반적인 API는

1, useState

구문

이 구문은 ES6 배열 구조이며, 배열의 첫 번째 값은 선언된 상태이고 두 번째는 각 값입니다. 상태를 바꾸는 함수이다.

각 프레임에는 독립된 상태가 있습니다

개인적으로는 각 프레임의 독립된 상태가 클로저 방식을 사용하여 구현된 것으로 알고 있습니다.
import React, { Component } from &#39;react&#39;

class MousePosition extends Component {
  constructor(props) {
    super(props)
    this.state = {
      x: 0,
      y: 0
    }
  }

  handleMouseMove = (e) => {
    const { clientX, clientY } = e
    this.setState({
      x: clientX,
      y: clientY
    })
  }

  componentDidMount() {
    document.addEventListener(&#39;mousemove&#39;, this.handleMouseMove)
  }

  componentWillUnmount() {
    document.removeEventListener(&#39;mousemove&#39;, this.handleMouseMove)
  }

  render() {
    const { children } = this.props
    const { x, y } = this.state
    return(
      <div>
        {
          children({x, y})
        }
      </div>
    )
  }

}

// 使用
class Index extends Component {
  constructor(props) {
    super(props)
  }

  render() {
    return (
      <MousePosition>
        {
          ({x, y}) => {
            return (
              <div>
                <p>x:{x}, y: {y}</p>
              </div>
            )
          }
        }
      </MousePosition>
    )
  }
}

export default Index
로그인 후 복사

컴포넌트의 상태나 소품이 업데이트되면 함수 컴포넌트가 렌더링을 위해 다시 호출되며, 각 렌더링은 독립적이며 고유한 독립적인 소품과 상태를 가지며 이는 다른 렌더링에 영향을 주지 않습니다.

2.useEffect

const [value, setValue] = useState(0)

Syntax

import React, { useEffect, useState } from &#39;react&#39;

function usePosition() {
  const [x, setX] = useState(0)
  const [y, setY] = useState(0)

  const handleMouseMove = (e) => {
    const { clientX, clientY } = e
    setX(clientX)
    setY(clientY)
  } 

  useEffect(() => {
    document.addEventListener(&#39;mousemove&#39;, handleMouseMove)
    return () => {
      document.removeEventListener(&#39;mousemove&#39;, handleMouseMove)
    }
  })
  return [
    {x, y}
  ]
}

// 使用
function Index() {
  const [position] = usePosition()
  return(
    <div>
      <p>x:{position.x},y:{position.y}</p>
    </div>
  )
}

export default Index
로그인 후 복사
useEffect는 콜백 함수와 종속성을 전달받으며, 내부의 콜백 함수는 종속성이 변경될 때만 실행됩니다. useEffect는 클래스 구성 요소 didMount, didUpdate 및 willUnmount의 수명 주기 기능과 유사합니다.

주의사항

useEffect는 비동기식이며 구성요소 렌더링이 완료된 후 실행됩니다.

useEffect의 콜백 함수는 부작용을 제거하거나

if를 반환하지 않는 처리 함수만 반환할 수 있습니다. useEffect가 전달됩니다. 종속성이 빈 배열이면 useEffect 내부 함수는 한 번만 실행됩니다

3. useMemo, useCallback
  • useMemo 및 useCallback은 주로 구성 요소 업데이트 수를 줄이고 구성 요소를 최적화하는 데 사용됩니다. 성능.

  • useMemo는 콜백 함수와 종속성을 전달받으며, 종속성이 변경된 경우에만 콜백 함수가 다시 실행됩니다.

  • useCallback은 콜백 함수와 종속성을 수신하고, 기억된 버전의 콜백 함수를 반환합니다. 기억된 버전은 종속성이 변경될 때만 다시 기억됩니다.

Syntax

function Example() {
  const [val, setVal] = useState(0)
  const timeoutFn = () => {
      setTimeout(() => {
        // 取得的值是点击按钮的状态,不是最新的状态
          console.log(val)
      }, 1000)
  }
  return (
      <>
          <p>{val}</p>
          <button onClick={()=>setVal(val+1)}>+</button>
          <button onClick={timeoutFn}>alertNumber</button>
      </>
  )
}
로그인 후 복사

우리는 일반적으로 클래스 컴포넌트에 대해 React.PureComponent를 사용합니다. PureComponent는 shouldUpdate에서 비교를 수행하여 함수 컴포넌트에 대해 업데이트가 필요한지 결정합니다. 우리는 일반적으로 React를 사용합니다. 메모. 하지만 React Hooks를 사용하면 각 렌더링 업데이트가 독립적이므로(새 상태가 생성됨) React.memo를 사용하더라도 여전히 다시 렌더링됩니다.

比如下面这种场景,改变子组件的name值后由于父组件更新后每次都会生成新值(addAge函数会改变),所以子组件也会重新渲染。

function Parent() {
  const [name, setName] = useState(&#39;cc&#39;)
  const [age, setAge] = useState(22)

  const addAge = () => {
    setAge(age + 1)
  }

  return (
    <>
      <p>父组件</p>
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <p>age: {age}</p>
      <p>-------------------------</p>
      <Child addAge={addAge} />
    </>
  )
}

const Child = memo((props) => {
  const { addAge } = props
  console.log(&#39;child component update&#39;)
  return (
    <>
      <p>子组件</p>
      <button onClick={addAge}>click</button>
    </>
  )
})
로그인 후 복사

使用useCallback优化

function Parent() {
  const [name, setName] = useState(&#39;cc&#39;)
  const [age, setAge] = useState(22)

  const addAge = useCallback(() => {
    setAge(age + 1)
  }, [age])

  return (
    <>
      <p>父组件</p>
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <p>age: {age}</p>
      <p>-------------------------</p>
      <Child addAge={addAge} />
    </>
  )
}

const Child = memo((props) => {
  const { addAge } = props
  console.log(&#39;child component update&#39;)
  return (
    <>
      <p>子组件</p>
      <button onClick={addAge}>click</button>
    </>
  )
})
로그인 후 복사

只有useCallback的依赖性发生变化时,才会重新生成memorize函数。所以当改变name的状态是addAge不会变化。

4、useRef

useRef类似于react.createRef。

const node = useRef(initRef)
로그인 후 복사

useRef 返回一个可变的 ref 对象,其 current 属性被初始化为传入的参数(initRef)

作用在DOM上

const node = useRef(null)
<input ref={node} />
로그인 후 복사

这样可以通过node.current属性访问到该DOM元素。

需要注意的是useRef创建的对象在组件的整个生命周期内保持不变,也就是说每次重新渲染函数组件时,返回的ref 对象都是同一个(使用 React.createRef ,每次重新渲染组件都会重新创建 ref)。

5、useReducer

useReducer类似于redux中的reducer。

语法

const [state, dispatch] = useReducer(reducer, initstate)
로그인 후 복사

useReducer传入一个计算函数和初始化state,类似于redux。通过返回的state我们可以访问状态,通过dispatch可以对状态作修改。

const initstate = 0;
function reducer(state, action) {
  switch (action.type) {
    case &#39;increment&#39;:
      return {number: state.number + 1};
    case &#39;decrement&#39;:
      return {number: state.number - 1};
    default:
      throw new Error();
  }
}
function Counter(){
    const [state, dispatch] = useReducer(reducer, initstate);
    return (
        <>
          Count: {state.number}
          <button onClick={() => dispatch({type: &#39;increment&#39;})}>+</button>
          <button onClick={() => dispatch({type: &#39;decrement&#39;})}>-</button>
        </>
    )
}
로그인 후 복사

6、useContext

通过useContext我们可以更加方便的获取上层组件提供的context。

父组件

import React, { createContext, Children } from &#39;react&#39;
import Child from &#39;./child&#39;

export const MyContext = createContext()

export default function Parent() {

  return (
    <div>
      <p>Parent</p>
      <MyContext.Provider value={{name: &#39;cc&#39;, age: 21}}>
        <Child />
      </MyContext.Provider>
    </div>
  )
}
로그인 후 복사

子组件

import React, { useContext } from &#39;react&#39;
import { MyContext } from &#39;./parent&#39;

export default function Parent() {
  const data = useContext(MyContext) // 获取父组件提供的context
  console.log(data)
  return (
    <div>
      <p>Child</p>
    </div>
  )
}
로그인 후 복사

使用步骤

  • 父组件创建并导出context:export const MyContext = createContext()
  • 父组件使用providervalue提供值:<MyContext.provide value={{name: &#39;cc&#39;, age: 22}} />
  • 子组件导入父组件的context:import { MyContext } from &#39;./parent&#39;
  • 获取父组件提供的值:const data = useContext(MyContext)

不过在多数情况下我们都不建议使用context,因为会增加组件的耦合性。

7、useLayoutEffect

useEffect 在全部渲染完毕后才会执行;useLayoutEffect 会在 浏览器 layout之后,painting之前执行,并且会柱塞DOM;可以使用它来读取 DOM 布局并同步触发重渲染。

export default function LayoutEffect() {
  const [color, setColor] = useState(&#39;red&#39;)
  useLayoutEffect(() => {
      alert(color) // 会阻塞DOM的渲染
  });
  useEffect(() => {
      alert(color) // 不会阻塞
  })
  return (
      <>
        <div id="myDiv" style={{ background: color }}>颜色</div>
        <button onClick={() => setColor(&#39;red&#39;)}>红</button>
        <button onClick={() => setColor(&#39;yellow&#39;)}>黄</button>
      </>
  )
}
로그인 후 복사

上面的例子中useLayoutEffect会在painting之前执行,useEffect在painting之后执行。

hooks让函数组件拥有了内部状态、生命周期,使用hooks让代码更加的简介,自定义hooks方便了对逻辑的复用,并且摆脱了class组件的this问题;但是在使用hooks时会产生一些闭包问题,需要仔细使用。

【相关推荐:Redis视频教程

위 내용은 반응 후크와 클래스의 차이점은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Python에서 클래스와 메서드를 사용하는 방법 Python에서 클래스와 메서드를 사용하는 방법 Apr 21, 2023 pm 02:28 PM

클래스와 메소드의 개념과 인스턴스 클래스(Class): 동일한 속성과 메소드를 가진 객체의 컬렉션을 설명하는 데 사용됩니다. 컬렉션의 모든 개체에 공통적인 속성과 메서드를 정의합니다. 객체는 클래스의 인스턴스입니다. 메소드: 클래스에 정의된 함수입니다. 클래스 구성 메서드 __init__(): 클래스에는 클래스가 인스턴스화될 때 자동으로 호출되는 init()라는 특수 메서드(구성 메서드)가 있습니다. 인스턴스 변수: 클래스 선언에서 속성은 변수로 표시됩니다. 이러한 변수를 인스턴스 변수라고 합니다. 인스턴스화: 클래스의 특정 개체인 클래스의 인스턴스를 만듭니다. 상속: 즉, 파생 클래스(derivedclass)가 기본 클래스(baseclass)를 상속합니다.

파이썬에서 클래스는 무엇을 의미합니까? 파이썬에서 클래스는 무엇을 의미합니까? May 21, 2019 pm 05:10 PM

클래스는 클래스를 정의하는 데 사용되는 키워드입니다. 클래스 뒤에 공백을 추가하고 클래스 이름을 추가합니다. 규칙: 첫 글자가 여러 개인 경우 카멜 표기법을 사용합니다. [class Dog()]와 같은 이름 지정.

jQuery를 사용하여 요소의 클래스 이름 바꾸기 jQuery를 사용하여 요소의 클래스 이름 바꾸기 Feb 24, 2024 pm 11:03 PM

jQuery는 웹 개발에 널리 사용되는 클래식 JavaScript 라이브러리로, 이벤트 처리, DOM 요소 조작, 웹 페이지에서 애니메이션 수행과 같은 작업을 단순화합니다. jQuery를 사용할 때 요소의 클래스 이름을 바꿔야 하는 상황이 자주 발생합니다. 이 기사에서는 몇 가지 실용적인 방법과 구체적인 코드 예제를 소개합니다. 1. RemoveClass() 및 addClass() 메소드 사용 jQuery는 삭제를 위한 RemoveClass() 메소드를 제공합니다.

PHP 클래스 사용법에 대한 자세한 설명: 코드를 더 명확하고 읽기 쉽게 만듭니다. PHP 클래스 사용법에 대한 자세한 설명: 코드를 더 명확하고 읽기 쉽게 만듭니다. Mar 10, 2024 pm 12:03 PM

PHP 코드를 작성할 때 클래스를 사용하는 것은 매우 일반적인 관행입니다. 클래스를 사용하면 관련 함수와 데이터를 단일 단위로 캡슐화하여 코드를 더 명확하고, 읽기 쉽고, 유지 관리하기 쉽게 만들 수 있습니다. 이 기사에서는 PHPClass의 사용법을 자세히 소개하고 구체적인 코드 예제를 제공하여 독자가 실제 프로젝트에 클래스를 적용하여 코드를 최적화하는 방법을 더 잘 이해할 수 있도록 돕습니다. 1. 클래스 생성 및 사용 PHP에서는 클래스 키워드를 사용하여 클래스를 정의하고 클래스의 속성과 메서드를 정의할 수 있습니다.

Vue 오류: v-bind를 사용하여 클래스와 스타일을 올바르게 바인딩할 수 없습니다. 어떻게 해결합니까? Vue 오류: v-bind를 사용하여 클래스와 스타일을 올바르게 바인딩할 수 없습니다. 어떻게 해결합니까? Aug 26, 2023 pm 10:58 PM

Vue 오류: v-bind를 사용하여 클래스와 스타일을 올바르게 바인딩할 수 없습니다. 어떻게 해결합니까? Vue 개발에서는 클래스와 스타일을 동적으로 바인딩하기 위해 v-bind 지시문을 사용하는 경우가 많지만, 클래스와 스타일을 바인딩하기 위해 v-bind를 올바르게 사용하지 못하는 등의 문제가 발생할 수도 있습니다. 이번 글에서는 이 문제의 원인을 설명하고 해결 방법을 알려드리겠습니다. 먼저 v-bind 지시어를 이해해 봅시다. v-bind는 V를 바인딩하는 데 사용됩니다.

SpringBoot가 사용자 정의 클래스 로더를 통해 클래스 파일을 암호화하고 보호하는 방법 SpringBoot가 사용자 정의 클래스 로더를 통해 클래스 파일을 암호화하고 보호하는 방법 May 11, 2023 pm 09:07 PM

배경 최근에는 jd-gui 등의 디컴파일 도구를 통해 엔지니어링 코드를 쉽게 복원하는 것을 방지하기 위해 회사 프레임워크에 대해 주요 비즈니스 코드를 암호화하고 있습니다. 관련 난독화 기법의 구성 및 사용이 상대적으로 복잡하고, springboot 프로젝트이므로 클래스 파일이 암호화된 후 사용자 정의 클래스로더가 해독되고 로드됩니다. 이 솔루션은 디컴파일의 난이도만 증가시키지만 전반적인 암호화 보호 흐름도는 표시되지 않습니다. 아래 그림에서 Maven 플러그인은 사용자 정의 Maven 플러그인을 사용하여 컴파일을 암호화하며, 암호화된 클래스 파일은 지정된 경로에 복사됩니다.

jquery에서 요소에 클래스가 있는지 확인하는 방법 jquery에서 요소에 클래스가 있는지 확인하는 방법 Mar 21, 2023 am 10:47 AM

jquery가 요소에 클래스가 있는지 확인하는 방법: 1. "hasClass('classname')" 메서드를 통해 요소에 특정 클래스가 있는지 확인합니다. 2. "is('.classname)을 통해 요소에 특정 클래스가 있는지 확인합니다. ')" 방법.

'[Vue 경고]: v-bind:class/ :class' 오류 해결 방법 '[Vue 경고]: v-bind:class/ :class' 오류 해결 방법 Aug 26, 2023 am 08:17 AM

"[Vuewarn]:v-bind:class/:class" 오류를 해결하는 방법 Vue를 사용하는 개발 과정에서 흔히 발생하는 오류 중 하나는 "[Vuewarn]:v-bind:class입니다. " /:클래스" 오류. 이 오류 메시지는 일반적으로 v-bind:class 또는 :class 속성을 사용할 때 나타납니다. 이는 Vue가 우리가 설정한 클래스 값을 올바르게 구문 분석할 수 없음을 나타냅니다. 그렇다면 만약

See all articles