갈고리 반응 기능 구성 요소: 당신이 알아야 할 모든 것

이 글은 최초로 https://www.devaradise.com/react-functional-component-with-hooks에 발표되었다
React에서 구성 요소를 만드는 데는 두 가지 방법이 있습니다. 하나는 기능 구성 요소이고, 다른 하나는 클래스 기반 구성 요소입니다.
2019년 2월 16일 React 16.8이 발표되기 전까지 우리는 항상 클래스 기반 구성 요소를 사용하여 상태 구성 요소(상태가 있는 React 구성 요소)를 만들었다.기능 구성 요소는 무상태 구성 요소를 만들 때만 사용됩니다.
현재, React 갈고리는 16.8 버전에 도입되었기 때문에, 우리는 클래스를 설명하지 않고 상태가 있는 구성 요소를 만들 수 있습니다.우리는 갈고리를 통해 기능 구성 요소로부터 React 상태와 생명주기 특성을 '갈고리' 할 수 있다.
관련 직위
  • React Conditional Rendering (If Else) Best Practices with 7 Different Methods
  • React Project Structure Best Practices for Scalable Application
  • React의 기능 성분은 무엇입니까?
    Functional Component는 간단한 javascript 함수를 사용하여 도구를 수락하고 JSX로 되돌아오는 React 구성 요소입니다.갈고리를 도입하기 전에도 무상태 부품이라고 불린다.
    현재 우리는 그것을 더 이상 무상태 구성 요소라고 할 수 없다. 왜냐하면 그것도 상태와 생명 주기가 있기 때문이다.
    갈고리의 존재로 인해React 기능 구성 요소는 클래스 기반 구성 요소를 대체할 수 있다. 왜냐하면 그것은 더욱 쉽게 작성되고, 더욱 짧으며, 테스트하기 쉬우며, 더욱 좋은 성능을 가지기 때문이다.
    기능 구성 요소는 어떻게 작성합니까?
    우리는 무상태 구성 요소에서 상태와 생명주기가 있는 복잡한 구성 요소까지 모든 종류의 react 구성 요소를 만들 수 있습니다.
    1. 간단한 무상태 구성 요소
    UI를 다시 사용할 수 있는 도구나 입력 또는 상태가 없는 간단한 무상태 구성 요소
    이것은 매우 기본적인 구성 요소로 기능 구성 요소로 작성하는 것이 가장 좋다.
    import React from 'react'
    
    export default function StatelessComponent() {
      return (
        <div>
          I am a stateless component
        </div>
      )
    }
    
    2. 처리 도구namerole 속성을 가진 무상태 구성 요소를 추가하고 싶다고 가정하십시오.그것은 다른 유사한 구성 요소에서 호출될 것이다.
    <StatelessComponent name="Syakir" role="Front-end Developer"/>
    
    제공된 입력/도구를 처리하려면 다음과 같은 방식으로 접근할 수 있습니다.
    import React from 'react'
    
    export default function StatelessComponent(props) {
      return (
        <div>
          Hi, I am {props.name}<br/>
          I am a {props.role}
        </div>
      )
    }
    
    기능 구성 요소에서 도구는 하나의 매개 변수(대상)를 통해 전달되며 이 매개 변수는 모든 입력/도구를 속성으로 저장합니다.
    3. 아이템 유형이 포함된 아이템
    더 좋은 구성 요소를 만들기 위해서는 도구를 정의하고 검증해야 합니다.PropTypes를 사용하여 이 목적을 실현할 수 있습니다.
    import React from 'react';
    import PropTypes from 'prop-types';
    
    export default function StatelessComponent(props) {
      return (
        <div>
          Hi, I am {props.name}<br/>
          I am a {props.age} years old {props.role}
        </div>
      )
    }
    
    StatelessComponent.propTypes = {
      name: PropTypes.string.isRequired,
      role: PropTypes.string.isRequired,
      age: PropTypes.number.isRequired
    };
    
    PropTypes를 사용하면 도구를 쉽게 입력하고 검사할 수 있습니다.제공된 도구가 정의된 유형과 일치하지 않으면 경고가 발생합니다.
    PropTypes에 대한 자세한 내용은 this page을 참조하십시오.
    4. 상태 구성 요소 있음(useState 갈고리 포함)
    현재, 우리는useState 갈고리를 사용하여 상태가 있는 기능 구성 요소를 만들 수 있습니다.
    다음은 당신이 그것을 어떻게 사용하는지입니다.
    import React, { useState } from 'react'
    
    export default function StatefulComponent() {
      const [helloMessage, setHelloMessage] = useState('Hello world!');
    
      return (
        <div>
          <input type="text" value={helloMessage}/>
        </div>
      )
    }
    
    
    useState 갈고리는 상태 변수를 선언하는 데 사용됩니다.이것은 현재 상태(helloMessage)와 업데이트 상태의 함수(setHelloMessage)를 되돌려줍니다.
    클래스 기반 구성 요소 중 this.state.helloMessagethis.setState에 해당한다.
    5. 이벤트 처리
    사용자가 폼, 단추, 링크 등 구성 요소와 상호작용을 할 때, 우리는 그들이 우리의 요구에 따라 일을 하기를 바란다.
    따라서, 우리는 이벤트 처리 프로그램이 onClick, onKeyup, onChange, other supported react events here 등 이벤트를 처리해야 한다.
    예를 들어 사용자가 입력 필드의 값을 변경할 때, 우리는 helloMessage을 변경하기를 희망합니다.너는 이렇게 할 수 있다.
    import React, { useState } from 'react'
    
    export default function StatefulComponent() {
      const [helloMessage, setHelloMessage] = useState('Hello world!');
    
      return (
        <div>
          <input type="text" value={helloMessage} onChange={(e) => setHelloMessage(e.target.value)}/>
          {helloMessage}
        </div>
      )
    }
    
    상태를 바꾸기 위해 코드 한 줄만 있으면 되기 때문에, 이벤트 처리 프로그램을 화살표 함수로 내연적으로 작성할 수 있습니다.
    변경 사항을 입력할 때 다른 코드를 추가하려면 이벤트 처리 프로그램을 단독 함수로 작성하는 것이 좋습니다. 아래와 같습니다.
    import React, { useState } from 'react'
    
    export default function StatefulComponent() {
      const [helloMessage, setHelloMessage] = useState('Hello world!');
    
      const onInputChange = (e) => {
        setHelloMessage(e.target.value);
        // other codes
      }
    
      return (
        <div>
          <input type="text" value={helloMessage} onChange={onInputChange}/>
          {helloMessage}
        </div>
      )
    }
    
    
    6. 콜백 처리(서브어셈블리에서 모 어셈블리로 데이터 전송)
    실제 프로젝트에서, 우리는 항상 하나의 구성 요소를 다른 구성 요소 (부모 구성 요소) 에 포장한다.
    많은 경우, 우리는 서브 구성 요소에서 발생하는 일을 경청하고, 부모 구성 요소에 처리 프로그램을 만들어야 한다.간단하게 말하자면, 우리는 데이터를 하위 구성 요소에서 부모 구성 요소로 전달해야 한다.
    우리는 리셋 함수를 통해 실현할 수 있다.
    리셋 함수는 매개 변수로 다른 함수에 전달된 함수로 외부 함수에서 그것을 호출하여 특정한 절차나 조작을 완성한다.
    https://developer.mozilla.org/en-US/docs/Glossary/Callback_function
    다음은 리셋 함수를 사용하여 데이터를 하위 레벨에서 부모 레벨로 전달하는 방법입니다.
    import React, {useState} from 'react';
    
    export default function ParentComponent() {
      const [messageFromChild, setMessageFromChild] = useState('');
    
      return (
        <div>
          parent should listen 'messageFromChild' when it changed: {messageFromChild}
          <br/><br/>
          <ChildComponent onChangeHelloMessage={(e) => setMessageFromChild(e)}/>
        </div>
      )
    }
    
    function ChildComponent({onChangeHelloMessage}) {
      const [helloMessage, setHelloMessage] = useState('Hello world!');
    
      const onInputChange = (e) => {
        setHelloMessage(e.target.value);
        onChangeHelloMessage(e.target.value);
      }
    
      return (
        <div>
          <input type="text" value={helloMessage} onChange={onInputChange}/>
          {helloMessage}
        </div>
      )
    }
    
    
    상기 코드의 리셋 함수는 onChangeHelloMessage이고 ChildComponent에서prop으로 전달된다.onChangeHelloMessage 값은 onInputChange 함수에서 호출됩니다.
    리셋 함수도 리셋 가능한 구성 요소를 만드는 데 자주 사용되며, 모든 상태는 부모 구성 요소를 호출하는 데 달려 있다.
    예를 들어, 우리는 사용자 정의 입력 구성 요소 (예를 들어 자동 완성, 입력 차단) 를 만들었는데, 이 구성 요소는 각 구성 요소 간에 공유된다.
    import React, {useState} from 'react';
    
    export default function ParentComponent() {
      const [customizedInputValue, setCustomizedInputValue] = useState('');
    
      return (
        <div>
          <ACustomizedInputComponent value={customizedInputValue} onChangeValue={(e) => setCustomizedInputValue(e.target.value)}/>
          <br/>    
          {customizedInputValue}
        </div>
      )
    }
    
    function ACustomizedInputComponent({value, onChangeValue}) {
      // Write some functions here that make this as a customized component.
      return (
        <div>
          {/* Just pretend this is a customized input that can't handled with the common input field */}
          <input type="text" value={value} onChange={onChangeValue}/>
        </div>
      )
    }
    
    
    보시다시피 ParentComponentACustomizedInputComponent의 상태를 제어하고 ACustomizedInputComponent의 변경 사항을 감청합니다.
    7. 기능 구성 요소 라이프 사이클(useEffect Hook)
    클래스 기반 구성 요소에는 componentDidMount, componentDidUpdate, componentWillUnmount 등 생명주기 방법이 있다.useEffect 갈고리 덕분에 우리는 지금 그것들을 교체하는 동등한 기능을 가질 수 있다.useEffect을 사용하면 렌더링 후에 React 구성 요소가 어떤 작업을 수행해야 하는지 알 수 있습니다.React은 전달한 함수를 기억하고 DOM 업데이트를 실행한 후에 호출합니다.
    실제 프로젝트에서 useEffect 갈고리는 일반적으로 API 호출 함수를 포장하는 데 사용된다.너는 나의 강좌에서 React Infinite scrolling에 관한 용법을 볼 수 있다.
    이 간단한 예에 대해 너는 아래의 코드를 볼 수 있다.
    import React, { useState, useEffect } from 'react';
    
    function Example() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        document.title = `You clicked ${count} times`;
      });
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    
    이것은 클래스 기반 구성 요소에 해당하는 코드입니다.
    class Example extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          count: 0
        };
      }
    
      componentDidMount() {
        document.title = `You clicked ${this.state.count} times`;
      }
      componentDidUpdate() {
        document.title = `You clicked ${this.state.count} times`;
      }
    
      render() {
        return (
          <div>
            <p>You clicked {this.state.count} times</p>
            <button onClick={() => this.setState({ count: this.state.count + 1 })}>
              Click me
            </button>
          </div>
        );
      }
    }
    
    useEffect의 진일보한 사용은 이 점을 이해하는 데 도움이 될 수 있습니다.
    왜 클래스 구성 요소가 아닌 기능 구성 요소를 사용합니까?
    React 응용 프로그램에서 전체적으로 기능 구성 요소를 사용하는 것에 대해 의문이 있다면, 클래스 구성 요소가 아닌 기능 구성 요소를 사용해야 하는 전체적인 이유입니다.
    1. 읽기 쉽고 쓰기 쉽다
    클래스 기반 구성 요소에 비해 기능 구성 요소는 이해하기 쉽고 작성 시간이 짧다.다음 코드를 보세요.
    import React from 'react';
    
    class Example extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          count: 0
        };
      }
    
      render() {
        return (
          <div>
            <p>You clicked {this.state.count} times</p>
            <button onClick={() => this.setState({ count: this.state.count + 1 })}>
              Click me
            </button>
          </div>
        );
      }
    }
    
    import React, { useState } from 'react';
    
    function Example() {
      const [count, setCount] = useState(0);
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    
    두 코드 블록은 같은 구성 요소이지만 성명 방식이 다르다.첫 번째 코드 블록은 클래스 기반 구성 요소 성명을 사용하고, 두 번째 코드 블록은 기능 구성 요소 성명을 사용합니다.
    기능 구성 요소에 대해 예시 구성 요소는 14줄 코드만 필요합니다.다른 한편, 클래스 기반 구성 요소 성명 코드를 사용하면 24줄 코드를 작성해야 한다.
    비교적 짧은 코드는 읽기 쉽다.
    2.테스트 용이성
    일반 자바스크립트 함수로 작성되었기 때문에 테스트 함수처럼 기능 구성 요소를 테스트할 수 있습니다.
    너도 숨겨진 상태나 부작용을 걱정할 필요가 없다.모든 입력(아이템)에 기능 구성 요소는 출력이 하나밖에 없습니다.
    3. 더 좋은 표현이 있을 수 있다
    function component 릴리즈 노트에서
    앞으로도 불필요한 검사와 메모리 분배를 피하고 이런 구성 요소에 대한 성능 최적화를 할 수 있다
    This article은 최적화되지 않아도 기능 구성 요소가 클래스 기반 구성 요소보다 45% 빠르다고 밝혔다.
    4. 적용 가능한 Best Practice
    비헤이비어가 아닌 사용자 인터페이스에 초점을 맞춘 표현 구성 요소를 만드는 데 사용되는 기능 구성 요소
    우리는 이런 구성 요소에 상태를 사용하는 것을 피해야 한다.더 높은 수준의 구성 요소에서 상태와 생명 주기를 사용해야 한다
    기능 구성 요소(무상태 구성 요소)를 사용하면 구성 요소의 순수함과 상태와 생명 주기가 없는 상태를 유지할 수 있다.
    5.React의 미래
    갈고리를 도입한 이래로 많은 개발자들이 기능 구성 요소를 사용하는데, 왜냐하면 지금은 클래스 기반 구성 요소가 할 수 있는 거의 모든 것을 할 수 있기 때문이다.
    그렇다면 왜 클래스 기반의 구성 요소를 사용하고 기능 구성 요소가 더 좋고 많은 개발자들이 그것을 좋아합니까?

    좋은 웹페이지 즐겨찾기