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


135

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

어떻게 오버라이드 (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>  
    )
}

1
기능 구성 요소에는 수명주기 메서드가 없어야합니다. 그들은 단지 기능이기 때문입니다. 함수에는 메서드가 없습니다. 클래스는 거기에있다
avalanche1

답변:


149

편집 : 의 도입으로 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>  
    )
  }
}

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


1
내가 말했듯이 구성 요소에 논리가 있고 요구 사항은 수명주기 기능을 사용하기를 원하며 기능 구성 요소로는 그렇게 할 수 없습니다. 그러니 수업을 더 잘 활용하십시오. 구성 요소가 더 추가 로직을 포함하지 않는 기능 컴포넌트 사용
하기 Shubham 카트리

1
이것은 componentDidUpdate에 해당하는 것과 정확히 일치하지 않습니다. useEffect(() => { // action here }, [props.counter])componentDidUpdate가 실행하지 않는 동안 초기 렌더링시 트리거됩니다.
Estus Flask

1
passing an empty array as second argument triggers the callback in useEffect only after the initial render이것은 물건을 빌드하는 더러운 해키 방법처럼 들립니다 : / 희망적으로 반응 팀은 향후 릴리스에서 더 나은 것을 제안 할 것입니다.
Lukas Liesis

3
그래서? componentwillmount에서 코드를 실행하는 방법에 대한 대답은 어디에 있습니까?
Toskan

59

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);

3
무엇입니까 Grid? 코드 스 니펫 어디에도 정의되어 있지 않습니까? 이것과 함께 redux를 사용하고 싶다면 다음과 같이 벗어날 수 export default lifecycle(methods)(connect({},{})(ComponentName))있습니까?
Sean Clancy

@SeanClancy 응답이 늦어서 죄송합니다. 코드 조각이 업데이트되었습니다.
Yohann

1
이것이 좋은 관행입니까? 이 솔루션에 도달하기 전에 다른 솔루션을 시도해야합니까? 아니면 가장 쉬운 방법을 찾으면 사용해도됩니까?
SuperSimplePimpleDimple

9

해결 방법 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);

4

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

유틸리티 기능

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]);
};  

2

문서에 따르면 :

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

useEffect(() => {


});

React 문서 참조


0

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

견본:

import React, { Component } from 'react';

class Grid extends Component {

 constructor(props){
  super(props)
 }

 componentDidMount () { /* do something */ }

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

}

2
수업을 사용하고 싶지 않습니다.
Aftab Naveed

3
문제는 클래스가 아닌 기능적 구성 요소와 함께 수명주기 메서드를 사용하는 방법이었습니다.
Mike

자, 함께 후크 반작용
가브리엘 페레이라

0

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')
)

0

당신이 사용하는 경우 사용이 후크 반응 할 수 16.8이 ... 반응 후크가 당신을하자 함수입니다 반작용 "에 훅"기능 구성 요소에서 상태 및 라이프 사이클 기능 반응 ... 문서

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.