React“componentDidUpdate”메소드를 언제 사용합니까?


108

나는 수십 개의 React파일을 썼고 절대 componentDidUpdate방법을 사용하지 않았습니다 .

이 방법을 사용해야하는 일반적인 예가 있습니까?

간단한 데모가 아닌 실제 사례를 원합니다.

답변 해주셔서 감사합니다!



로드시 구성 요소의 초기 상태를 설정하려는 간단한 경우입니다.
Rajesh

@Rajesh 설명하거나 예를 들어 줄 수 있습니까? 감사!
slideshowp2

1
가장 일반적인 사용 사례는 React와 함께 DOM에서 직접 작동하는 다른 라이브러리 (jQuery, D3 ...)가있는 경우입니다. 이러한 시나리오에서 다른 라이브러리가 DOM 변환을 수행해야하는 경우 componentDidUpdate를 사용하여 React의 shadow DOM이 실제 DOM으로 플러시되었는지 확인해야합니다.
Jorge

1
@Jorge의 의견에 대해 자세히 설명하기 위해 : 가장 일반적인 경우는 React가 업데이트 된 후 실제 DOM에서 읽는 것입니다. 예를 들어 DOM 요소의 정확한 크기 또는 뷰포트에서 DOM 요소의 위치를 ​​알고 싶을 때. 예를 들어 반응을 관리하려는 애니메이션 또는 전환의 경우. 반응이 렌더링 된 후 DOM을 변경하기 위해 jQuery를 사용하지 않는 것이 좋습니다. 반응 + 다른 라이브러리가 동일한 DOM 부분을 변경하는 것은 나쁜 생각입니다.
wintvelt

답변:


88

간단한 예는 사용자로부터 입력 데이터를 수집 한 다음 Ajax를 사용하여 해당 데이터를 데이터베이스에 업로드하는 앱입니다. 다음은 간단한 예입니다 (실행하지 않았 음-구문 오류가있을 수 있음).

export default class Task extends React.Component {
  
  constructor(props, context) {
    super(props, context);
    this.state = {
      name: "",
      age: "",
      country: ""
    };
  }

  componentDidUpdate() {
    this._commitAutoSave();
  }

  _changeName = (e) => {
    this.setState({name: e.target.value});
  }

  _changeAge = (e) => {
    this.setState({age: e.target.value});
  }

  _changeCountry = (e) => {
    this.setState({country: e.target.value});
  }

  _commitAutoSave = () => {
    Ajax.postJSON('/someAPI/json/autosave', {
      name: this.state.name,
      age: this.state.age,
      country: this.state.country
    });
  }

  render() {
    let {name, age, country} = this.state;
    return (
      <form>
        <input type="text" value={name} onChange={this._changeName} />
        <input type="text" value={age} onChange={this._changeAge} />
        <input type="text" value={country} onChange={this._changeCountry} />
      </form>
    );
  }
}

따라서 구성 요소에 state변경 사항 이있을 때마다 데이터가 자동 저장됩니다. 그것을 구현하는 다른 방법도 있습니다. 는 componentDidUpdate작업이 일어날 필요가있을 때 특히 유용 DOM을 업데이트하고, 업데이트 큐가 비워집니다. 아마 복잡한에 가장 유용 renders하고 state또는 DOM을 변경하거나 할 무언가를 필요로 할 때 절대적으로 마지막 실행 할 수 있습니다.

위의 예는 다소 간단하지만 요점을 증명할 수 있습니다. 지금은 모든 키 입력에서 실행되기 때문에 자동 저장이 실행될 수있는 시간 (예 : 최대 10 초마다)을 제한하는 것이 개선 될 수 있습니다.

바이올린 에 대한 데모도 만들었습니다 .


자세한 내용은 공식 문서를 참조하십시오 .

componentDidUpdate()업데이트가 발생한 직후에 호출됩니다. 이 메서드는 초기 렌더링에는 호출되지 않습니다.

구성 요소가 업데이트되었을 때이를 DOM에서 작동 할 수있는 기회로 사용하십시오. 이것은 또한 현재 props를 이전 props와 비교하는 한 네트워크 요청을하기에 좋은 곳입니다 (예 : props가 변경되지 않았다면 네트워크 요청이 필요하지 않을 수 있습니다).


내 생각 this.setState({...}, callback)callback동일을 _commitAutoSave당신은 어떻게 생각하십니까? 그래서,이 사건은 componentDidUpdate방법 을 사용할 수 있다고 생각 하지만, 꼭 그렇지는 않습니다. 맞습니까? 바이올린
slideshowp2

1
예, 콜백을 사용할 수 있지만 연속적으로 실행되는 여러 setState가있는 경우 문제가 더 까다로워집니다.
크리스

답변 해 주셔서 감사합니다. 따라서 사용할 한 가지 경우 componentDidUpdate는 여러 setState를 해결하는 것입니다! 다른 아이디어가 있습니까?
slideshowp2

@novaline 나는 그들이 react-sound 구성 요소 github.com/leoasis/react-sound/blob/master/src/index.js 에서 그것을 사용하는 것을 봅니다 .. 그들이 그것을 사용하는 이유를 정확히 모르겠지만 나는 생각했습니다 당신이 살펴볼 수 있도록 링크를 공유하겠습니다.
Sarah

3
이것은 좋은 예이지만 React 문서의 주요 권장 사항이 누락되었습니다. "현재 props를 이전 props와 비교하는 한 네트워크 요청을 수행하기에 좋은 곳입니다 (예 : props가 변경되지 않은 경우 네트워크 요청이 필요하지 않을 수 있음)." reactjs.org/docs/react-component.html#componentdidupdate 마찬가지로 setStateCDU를 호출 할 때마다 조건부 논리로 호출을 래핑해야합니다 .
theUtherSide

5

경우에 따라 생성자 또는 componentDidMount의 props에서 상태 값을 추가 할 수 있습니다. props가 변경되었지만 구성 요소가 이미 마운트되어 있으므로 componentDidMount가 실행되지 않고 생성자도 실행되지 않을 때 setState를 호출해야 할 수 있습니다. 이 특별한 경우에는 props가 변경되었으므로 componentDidUpdate를 사용할 수 있으며, 새로운 props로 componentDidUpdate에서 setState를 호출 할 수 있습니다.


2

나는 componentDidUpdate()highchart에서 사용 했습니다.

다음은이 구성 요소의 간단한 예입니다.

import React, { PropTypes, Component } from 'react';
window.Highcharts = require('highcharts');

export default class Chartline extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      chart: ''
    };
  }

  public componentDidUpdate() {
    // console.log(this.props.candidate, 'this.props.candidate')
    if (this.props.category) {
      const category = this.props.category ? this.props.category : {};
      console.log('category', category);
      window.Highcharts.chart('jobcontainer_' + category._id, {
        title: {
          text: ''
        },
        plotOptions: {
          series: {
            cursor: 'pointer'
          }
        },
        chart: {
          defaultSeriesType: 'spline'
        },
        xAxis: {
          // categories: candidate.dateArr,
          categories: ['Day1', 'Day2', 'Day3', 'Day4', 'Day5', 'Day6', 'Day7'],
          showEmpty: true
        },
        labels: {
          style: {
            color: 'white',
            fontSize: '25px',
            fontFamily: 'SF UI Text'
          }
        },
        series: [
          {
            name: 'Low',
            color: '#9B260A',
            data: category.lowcount
          },
          {
            name: 'High',
            color: '#0E5AAB',
            data: category.highcount
          },
          {
            name: 'Average',
            color: '#12B499',
            data: category.averagecount
          }
        ]
      });
    }
  }
  public render() {
    const category = this.props.category ? this.props.category : {};
    console.log('render category', category);
    return <div id={'jobcontainer_' + category._id} style={{ maxWidth: '400px', height: '180px' }} />;
  }
}

2
componentDidUpdate(prevProps){ 

    if (this.state.authToken==null&&prevProps.authToken==null) {
      AccountKit.getCurrentAccessToken()
      .then(token => {
        if (token) {
          AccountKit.getCurrentAccount().then(account => {
            this.setState({
              authToken: token,
              loggedAccount: account
            });
          });
        } else {
          console.log("No user account logged");
        }
      })
      .catch(e => console.log("Failed to get current access token", e));

    }
}

1

이 수명주기 메서드는 업데이트가 발생하는 즉시 호출됩니다. componentDidUpdate () 메서드의 가장 일반적인 사용 사례는 prop 또는 상태 변경에 대한 응답으로 DOM을 업데이트하는 것입니다.

이 라이프 사이클에서 setState ()를 호출 할 수 있지만 이전 상태에서 상태 또는 prop 변경 사항을 확인하려면 조건으로 래핑해야합니다. setState ()를 잘못 사용하면 무한 루프가 발생할 수 있습니다. 이 수명주기 방법의 일반적인 사용 예를 보여주는 아래 예를 살펴보세요.

componentDidUpdate(prevProps) {
 //Typical usage, don't forget to compare the props
 if (this.props.userName !== prevProps.userName) {
   this.fetchData(this.props.userName);
 }
}

위의 예에서 현재 소품을 이전 소품과 비교하고 있음을 알 수 있습니다. 이것은 현재의 props가 변경되었는지 확인하기위한 것입니다. 이 경우 소품이 변경되지 않은 경우 API를 호출 할 필요가 없습니다.

자세한 내용은 공식 문서를 참조하세요 .


의 경우 어떻게해야합니까 this.fetchData is not a function?
tomrlh

tomrlh 그것은 함수 호출입니다
Kashif

0

상태의 무언가가 변경되어 부작용 (예 : api 요청-가져 오기, 넣기, 게시, 삭제)을 호출해야 할 때. 당신이 호출 할 필요가 그래서 componentDidUpdate()때문에componentDidMount() 이미이라고합니다.

componentDidUpdate ()에서 부작용을 호출 한 후 .NET의 응답 데이터를 기반으로 상태를 새 값으로 설정할 수 있습니다 then((response) => this.setState({newValue: "here"})). 상태를 새 값으로 설정하면 componentDidUpdate ()가 다시 호출되므로 무한 루프 를 확인 prevProps하거나 prevState방지 해야 합니다.

모범 사례를 위해 부작용을 호출 할 수있는 두 곳이 있습니다-componentDidMount () 및 componentDidUpdate ()

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