[reactjs] 함수 컴포넌트 내부의 ReactJS 라이프 사이클 메소드

클래스 내부에 구성 요소를 작성하는 대신 함수 구문을 대신 사용하고 싶습니다.

어떻게 오버라이드 (override) 할 componentDidMount, componentWillMount기능 구성 요소 내부에?
가능할까요?

const grid = (props) => {
    console.log(props);
    let {skuRules} = props;

    const componentDidMount = () => {
        if(!props.fetched) {
            props.fetchRules();
        }
        console.log('mount it!');
    };
    return(
        <Content title="Promotions" breadcrumbs={breadcrumbs} fetched={skuRules.fetched}>
            <Box title="Sku Promotion">
                <ActionButtons buttons={actionButtons} />
                <SkuRuleGrid
                    data={skuRules.payload}
                    fetch={props.fetchSkuRules}
                />
            </Box>
        </Content>
    )
}



답변

편집 : 의 도입으로 Hooks이 행동의 라이프 사이클의 종류뿐만 아니라 기능적인 구성 요소의 상태를 구현하는 것이 가능하다. 현재

후크는 클래스를 작성하지 않고도 상태 및 기타 React 기능을 사용할 수있는 새로운 기능 제안입니다. v16.8.0 의 일부로 React에서 릴리스되었습니다.

useEffect후크는 수명주기 동작을 복제하는 데 사용할 useState수 있으며 함수 구성 요소에 상태를 저장하는 데 사용할 수 있습니다.

기본 구문 :

useEffect(callbackFunction, [dependentProps]) => cleanupFunction

다음과 같은 후크에서 사용 사례를 구현할 수 있습니다.

const grid = (props) => {
    console.log(props);
    let {skuRules} = props;

    useEffect(() => {
        if(!props.fetched) {
            props.fetchRules();
        }
        console.log('mount it!');
    }, []); // passing an empty array as second argument triggers the callback in useEffect only after the initial render thus replicating `componentDidMount` lifecycle behaviour

    return(
        <Content title="Promotions" breadcrumbs={breadcrumbs} fetched={skuRules.fetched}>
            <Box title="Sku Promotion">
                <ActionButtons buttons={actionButtons} />
                <SkuRuleGrid
                    data={skuRules.payload}
                    fetch={props.fetchSkuRules}
                />
            </Box>
        </Content>
    )
}

useEffect구성 요소가 마운트 해제 될 때 실행될 함수를 반환 할 수도 있습니다. 이것은 리스너 구독을 취소하고 다음의 동작을 복제하는 데 사용할 수 있습니다 componentWillUnmount.

예 : componentWillUnmount

useEffect(() => {
    window.addEventListener('unhandledRejection', handler);
    return () => {
       window.removeEventListener('unhandledRejection', handler);
    }
}, [])

useEffect특정 이벤트를 조건부로 만들려면 변경 사항을 확인하기 위해 값 배열을 제공 할 수 있습니다.

예 : componentDidUpdate

componentDidUpdate(prevProps, prevState) {
     const { counter } = this.props;
     if (this.props.counter !== prevState.counter) {
      // some action here
     }
}

동등한 후크

useEffect(() => {
     // action here
}, [props.counter]); // checks for changes in the values in this array

이 배열을 포함하는 경우 시간에 따라 변경되는 구성 요소 범위의 모든 값 (props, state)을 포함해야합니다. 그렇지 않으면 이전 렌더링의 값을 참조하게 될 수 있습니다.

사용에는 약간의 미묘함이 있습니다 useEffect. API를 확인하십시오 Here.


v16.7.0 이전

함수 구성 요소의 속성은 Reacts 수명주기 함수 또는 this키워드에 액세스 할 수 없다는 것 입니다. React.Component라이프 사이클 함수를 사용하려면 클래스 를 확장해야 합니다.

class Grid extends React.Component  {
    constructor(props) {
       super(props)
    }

    componentDidMount () {
        if(!this.props.fetched) {
            this.props.fetchRules();
        }
        console.log('mount it!');
    }
    render() {
    return(
        <Content title="Promotions" breadcrumbs={breadcrumbs} fetched={skuRules.fetched}>
            <Box title="Sku Promotion">
                <ActionButtons buttons={actionButtons} />
                <SkuRuleGrid
                    data={skuRules.payload}
                    fetch={props.fetchSkuRules}
                />
            </Box>
        </Content>
    )
  }
}

함수 구성 요소는 추가 논리없이 구성 요소 만 렌더링하려는 경우에 유용합니다.


답변

react-pure-lifecycle 을 사용 하여 기능 구성 요소에 수명주기 함수를 추가 할 수 있습니다 .

예:

import React, { Component } from 'react';
import lifecycle from 'react-pure-lifecycle';

const methods = {
  componentDidMount(props) {
    console.log('I mounted! Here are my props: ', props);
  }
};

const Channels = props => (
<h1>Hello</h1>
)

export default lifecycle(methods)(Channels);


답변

해결 방법 1 :
새로운 반응 HOOKS API를 사용할 수 있습니다 . 현재 React v16.8.0에 있음

후크를 사용하면 클래스없이 React의 더 많은 기능을 사용할 수 있습니다.
후크는 이미 알고있는 React 개념 (props, state, context, refs 및 lifecycle)에 대한보다 직접적인 API를 제공합니다 . Hooks는 Recompose로 해결 된 모든 문제를 해결합니다.

작성자의 메모 recompose(acdlite, 2018 년 10 월 25 일) :

안녕하세요! 저는 약 3 년 전에 Recompose를 만들었습니다. 그로부터 약 1 년 후 저는 React 팀에 합류했습니다. 오늘 우리는 Hooks에 대한 제안을 발표했습니다. Hooks는 내가 3 년 전에 Recompose로 해결하려했던 모든 문제를 해결 해줍니다. 이 패키지의 활성 유지 관리를 중단하고 (향후 React 릴리스와의 호환성을위한 버그 수정 또는 패치 제외) 사람들이 대신 Hooks를 사용하도록 권장합니다. Recompose를 사용하는 기존 코드는 계속 작동하며 새로운 기능을 기대하지 마십시오.

해결 방법 2 :

후크를 지원하지 않는 리 액트 버전을 사용하고 있다면 걱정하지 마세요 recompose. 대신 (기능 컴포넌트 및 상위 컴포넌트를위한 리 액트 유틸리티 벨트.)를 사용하세요. 기능 구성 요소 recompose에 연결 lifecycle hooks, state, handlers etc하는 데 사용할 수 있습니다 .

다음 은 수명주기 HOC (재구성에서)를 통해 수명주기 메서드 를 연결하는 렌더링없는 구성 요소입니다 .

// taken from https://gist.github.com/tsnieman/056af4bb9e87748c514d#file-auth-js-L33

function RenderlessComponent() {
  return null;
}

export default lifecycle({

  componentDidMount() {
    const { checkIfAuthed } = this.props;
    // Do they have an active session? ("Remember me")
    checkIfAuthed();
  },

  componentWillReceiveProps(nextProps) {
    const {
      loadUser,
    } = this.props;

    // Various 'indicators'..
    const becameAuthed = (!(this.props.auth) && nextProps.auth);
    const isCurrentUser = (this.props.currentUser !== null);

    if (becameAuthed) {
      loadUser(nextProps.auth.uid);
    }

    const shouldSetCurrentUser = (!isCurrentUser && nextProps.auth);
    if (shouldSetCurrentUser) {
      const currentUser = nextProps.users[nextProps.auth.uid];
      if (currentUser) {
        this.props.setCurrentUser({
          'id': nextProps.auth.uid,
          ...currentUser,
        });
      }
    }
  }
})(RenderlessComponent);


답변

자신 만의 라이프 사이클 방법을 만들 수 있습니다.

유틸리티 기능

import { useEffect, useRef } from "react";

export const componentDidMount = handler => {
  return useEffect(() => {
    return handler();
  }, []);
};

export const componentDidUpdate = (handler, deps) => {
  const isInitialMount = useRef(true);

  useEffect(() => {
    if (isInitialMount.current) {
      isInitialMount.current = false;

      return;
    }

    return handler();
  }, deps);
};

용법

import { componentDidMount, componentDidUpdate } from "./utils";

export const MyComponent = ({ myProp }) => {
  componentDidMount(() => {
    console.log("Component did mount!");
  });

  componentDidUpdate(() => {
    console.log("Component did update!");
  });

  componentDidUpdate(() => {
    console.log("myProp did update!");
  }, [myProp]);
};  


답변

문서에 따르면 :

import React, { useState, useEffect } from 'react'
// Similar to componentDidMount and componentDidUpdate:

useEffect(() => {


});

React 문서 참조


답변

React LifeCycle을 사용하려면 Class를 사용해야합니다.

견본:

import React, { Component } from 'react';

class Grid extends Component {

 constructor(props){
  super(props)
 }

 componentDidMount () { /* do something */ }

 render () {
   return <h1>Hello</h1>
 }

}


답변

create-react-class 모듈을 사용할 수 있습니다.
공식 문서

물론 먼저 설치해야합니다.

npm install create-react-class

다음은 작동하는 예입니다.

import React from "react";
import ReactDOM from "react-dom"
let createReactClass = require('create-react-class')


let Clock = createReactClass({
    getInitialState:function(){
        return {date:new Date()}
    },

    render:function(){
        return (
            <h1>{this.state.date.toLocaleTimeString()}</h1>
        )
    },

    componentDidMount:function(){
        this.timerId = setInterval(()=>this.setState({date:new Date()}),1000)
    },

    componentWillUnmount:function(){
        clearInterval(this.timerId)
    }

})

ReactDOM.render(
    <Clock/>,
    document.getElementById('root')
)