클래스 구성 요소를 기능 구성 요소로 변환(기본 구조, 상태 및 수명 주기 메서드)
이 튜토리얼에서는 기존 React 프로젝트의 기본 구조, 상태 및 수명 주기 메서드를 기능적 구성 요소 및 후크로 변환하는 방법을 살펴보겠습니다. 클래스 구성 요소와 함께 React를 사용하기 시작했고 이 변환에 익숙하지 않은 경우 이 튜토리얼은 당신을 위한 것입니다.
정리를 위해 다음은 제가 다룰 주제입니다.
목차
기본 구조
this  keyword render()  method props  object 상태
수명 주기 방법
TL;DR
클래스 구성 요소
기능적 구성요소
화살표 함수를 사용하지 않는 한 메서드 바인딩 필요
바인딩 필요 없음
this 키워드 사용아니요
this 키워드render() 방법아니오
render() 방법props 생성자props 기능 구성 요소의 매개 변수로처음에
state 객체 정의사용
useState 훅state 개체만 될 수 있습니다state는 객체, 배열, 정수, 문자열 등이 될 수 있습니다.하나의 상태 개체만
여러 개
state 조각this.setState 상태 개체를 병합합니다.Setter 메서드는 상태 값을 대체합니다.
this.setState 두 번째 인수로 선택적 콜백 함수를 허용합니다.그렇지 않다
별도의 기능으로 가장 중요한 3가지 라이프 사이클 방법
useEffect 한 번에 세 가지를 모두 모방할 수 있습니다.componentDidUpdate는 초기 렌더링에서 실행되지 않습니다.비어 있지 않은 종속성이 있는
useEffect 초기 렌더링에서도 실행됩니다.props 메서드에서 state 또는 componentDidUpdate 개체의 변경 사항을 수동으로 확인해야 합니다.useEffect의 두 번째 매개변수인 종속성 배열이 자동으로 처리합니다.기본 구조
클래스와 함수형 컴포넌트의 구조는 언뜻 보기에는 달라 보이지만, 함수형 컴포넌트에서는 클래스 컴포넌트의 대부분이 생략되거나 지나치게 단순화되어 있습니다.
바인딩 클래스 메서드
When we create a method in a class component, we have to bind it to this object (unless you create your method as an arrow function) so that we can use it in our component.
class MyComponent extends React.Component {
    constructor() {
        super();
        this.myMethod = this.myMethod.bind(this);
    }
    myMethod() { 
        // do stuff
    }
    render() {
        return // some jsx
    }
}
 
 
In a functional component, no binding is necessary because there is no class. You may create your methods inside your component's function definition as you like (function definition, assignment to a variable, etc.)
const MyComponent = () => {
    const myMethod = () => {
        // do stuff
    }
    return // some jsx
}
 
 
이 키워드
In a functional component, we no longer need the  this  keyword. There is no class instance, so we do not refer to our  state ,  props , or methods as a member of the class. Let's continue from the previous example. If we are to refer to the  myMethod  function in our JSX, we would do it like this:
<button onClick={myMethod}>My Button</button>
 
 
렌더링() 메서드
In a functional component, we also do not need the  render()  method anymore. Whatever our functional component returns become our component's JSX.
소품 개체
This is an obvious one because you probably used stateless functional components before, but I did not want to skip it.
In class components, you pass  props  to the base constructor so that you have access to the  props  object as  this.props .
class MyComponent extends React.Component {
    constructor(props) {
        super(props);
    }
    // do stuff
}
 
 
In a functional component,  props  comes as a parameter to the component's function definition.
function MyComponent(props) {
    // do stuff
}
 
 
상태
state 클래스 및 기능 구성 요소를 처리하는 것은 크게 다르지 않습니다. 가장 중요한 부분은 아마도 클래스 컴포넌트의 setState 메소드와 기능 컴포넌트의 setter 메소드의 차이점을 이해하는 것입니다.상태 생성
In older versions of React, the state used to be defined in the constructor. Later on, it changed so that you can define a state object right at the beginning of your component.
In older versions:
class MyComponent extends React.Component {
    constructor() {
        this.state = { myState: "my value" }
    }
    // do stuff
}
 
 
Newer versions:
class MyComponent extends React.Component {
    state = { myState: "my value" }
    // do stuff
}
 
 
In functional components, you need to use the  useState  hook for creating a new state piece. Also, in the class components,  state  has to be an object and there can be only one state object in a class component. This is not the case when creating a state with the  useState  hook.
const MyComponent = () => {
    const [myState, setMyState] = useState('my value');
    const [myNumber, setMyNumber] = useState(22);
    const [myBool, setMyBool] = useState(false);
    // do stuff
}
 
 
Here, we created 3 different pieces of  state  for one component. One is a string, one is an integer, and one is a boolean value.
Let's explain the way we create a  state  here.
 useState  hook returns a tuple with two elements: the first one is the value of the  state  we created, the second one is a function for updating that specific piece of state, which brings me to the next topic.
상태 업데이트 중
When we are updating our state in class components, we utilize React's  setState  function which has a slightly different API compared to the setter method returned from the  useState  hook.
class MyComponent extends React.Component {
    state = { 
        myState: "my value", 
        myOtherState: "my other value" 
    }
    updateMyState = () => {
        this.setState({ myState: "my newer value" });
    }
    render() {
        // After running this.updateMyState()
        console.log(this.state); // { myState: "my newer value", myOtherState: "my other value"}
        return // some JSX
    }
}
 
 
We pass an object to the  this.setState  method with the keys that we desire to update.  this.setState  automatically merges the passed state into the existing state. This is not the case when we are dealing with  state  as objects in functional components.
const MyComponent = () => {
    const [myState, setMyState] = useState({ 
        myState: "my value", 
        myOtherState: "my other value" 
    });
    const updateMyState = () => {
        setMyState({ myState: "my newer value" });
    }
    // After running updateMyState()
    console.log(myState); // { myState: "my newer value" }
    return // some JSX
}
 
 
Another difference is that the second argument of  setState  accepts an optional callback function in class components to run after the state change happens. Even though the React documentation does not recommend using this method and instead recommends using the  componentDidUpdate  life-cycle method, you might be inclined to think that the setter method returned from  useState  in functional components would provide the same optional callback feature. But it does not.
소비 상태
This is a fairly easy one. Referring to a piece of state in a class component:  this.state.myState .
In a functional component, whatever name you gave your state while de-structuring from the  useState  hook, that's your  state  name.
수명 주기 방법
수명 주기 방법은 지금까지 설명한 방법에 비해 조금 더 까다로워 보일 수 있습니다. 여기서 논의할 세 가지 수명 주기 방법을 모두 모방하기 위해
useEffect 후크를 사용합니다.componentDidMount
We use this life-cycle method for the side effects of our component, such as calling an API, etc. when the component is initially rendered. Everything inside this method is called once the initial rendering of the component is completed.
class MyComponent extends React.Component {
    // state, etc.
    componentDidMount() {
        this.fetchSomeData();
    }
    // do stuff
}
 
 
To do the same thing in a functional component, we make use of our  useEffect  hook.  useEffect  takes two parameters: the first one is a function to call, the second one is an optional dependency array.
const MyComponent = () => {
    // state, etc.
    useEffect(() => {
        fetchSomeData();
    }, []);
    // do stuff
}
 
 
When imitating  componentDidMount , we leave the second dependency array empty. Why? Because React looks at that array and executes the function in  useEffect  if any value in that array changes. Since we only want to fetch our data once the component is initially rendered, we leave that array empty. An empty array means, "Hey React, watch this empty array. If anything changes, execute the function I gave you."
Here is an important note: whether we leave the dependency array empty, pass values in it, or don't even pass the array itself to  useEffect ; either way React executes the function in  useEffect  in the initial rendering, which brings me to the next life-cycle method.
componentDidUpdate(prevProps, prevState)
This life-cycle method is invoked after an update in  props  or  state  object occurs. It takes two parameters  prevProps  and  prevState  so we can check if the current  props  or  state  has changed in the last component update.
class MyComponent extends React.Component {
    // state, props, etc.
    componentDidUpdate(prevProps) {
        if (this.props.id !== prevProps.id) {
            this.fetchData(this.props.id);
        }
    }
    // do stuff
}
 
 
Here we are checking if  this.props.id  has changed or not. If changed, we are fetching new data based on the new id.  useEffect  saves us some time when checking if the  props  object has changed or not.
const MyComponent = (props) => {
    // state, etc.
    useEffect(() => {
        fetchData(props.id);
    }, [props.id]);
    // do stuff
}
 
 
We made use of the dependency array I was talking about earlier. Now React will watch props.id value and execute the function if it changes. I want to remind again: The function in  useEffect  will be executed in the initial render as well as following updates on  props.id  while  componentDidUpdate  will not be executed in the initial render.
If you remove the dependency array completely, the function in  useEffect  will run in every update of the component.
componentWillUnmount
This life-cycle method is invoked right before the component is unmounted. If you have ongoing side-effects that you started earlier such as a network request or a timer, this is the place you clean them up.
class MyComponent extends React.Component {
    state = { counter: 0 }
    componentDidMount() {
        this.myTimer = setInterval(() => {
            this.setState({ counter: this.state.counter + 1 })
        }, 1000);
    }
    componentWillUnmount() {
        clearInterval(this.myTimer);
    }
    // do stuff
}
 
 
Here we created a timer in our  componentDidMount  life-cycle method. It updates and increases  this.state.counter  every second. If we do not clear this up in the  componentWillUnmount  life-cycle method, we will get  Can't perform a React state update on an unmounted component  error after the component is unmounted.
To do the same thing in functional components, we make use of the  return  keyword inside our function in  useEffect . Let's create the same thing in a functional component.
const MyComponent = (props) => {
    const [counter, setCounter] = useState(0);
    useEffect(() => {
        const myTimer = setInterval(() => {
            setCounter(counter => counter + 1);
        }, 1000);
        return () => {
            clearInterval(myTimer);
        }
    }, []);
    // do stuff
}
 
 
In case you haven't realized already, we did imitate  componentDidMount  and  componentWillUnmount  under one  useEffect  call.
setCounter  method:  setCounter(counter => counter + 1) . This is to avoid stale closures. Dmitri Pavlutin explain what a stale closure is  here 들어보지 못한 경우를 대비해 아주 잘 알고 있습니다.마지막 생각들
기존 React 프로젝트를 클래스 구성 요소에서 기능 구성 요소로 변환하는 것은 번거롭게 보일 수 있습니다.
후크가 처음 도입되었을 때 React 팀은 Gradual Adoption Strategy 을 제안했습니다. 그러나 그로부터 거의 2년이 지났고 실제로 후크 덕분에 클래스 구성 요소에서 할 수 있는 것이 많지 않지만 기능적 구성 요소에서는 할 수 없습니다.
또한 대부분의 라이브러리는 후크와 함께 설계된 새로운 API를 제공하여 후크를 채택하고 있습니다. 많은 React 개발자는 React로 앱을 빌드하는 명확하고 간결한 방법으로 후크를 찾습니다. 지금까지 후크가 있는 기능적 구성 요소를 사용한 적이 없다면 지금이 고려를 시작할 때라는 것이 제 개인적인 생각입니다.
Reference
이 문제에 관하여(클래스 구성 요소를 기능 구성 요소로 변환(기본 구조, 상태 및 수명 주기 메서드)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/sametweb/converting-class-components-to-function-components-basic-structure-state-life-cycle-methods-50cd텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)