IT이야기

생성자에서 상태를 정의하거나 속성 이니셜라이저를 사용하는 것이 더 낫은가

cyworld 2021. 10. 12. 20:16
반응형

생성자에서 상태를 정의하거나 속성 이니셜라이저를 사용하는 것이 더 낫습니까?


babel 문서 에 따르면 React와 함께 ES6+를 사용하는 올바른 방법은 다음과 같은 초기 구성 요소입니다.

class Video extends React.Component {
  static defaultProps = {
    autoPlay: false,
    maxLoops: 10,
  }
  static propTypes = {
    autoPlay: React.PropTypes.bool.isRequired,
    maxLoops: React.PropTypes.number.isRequired,
    posterFrameSrc: React.PropTypes.string.isRequired,
    videoSrc: React.PropTypes.string.isRequired,
  }
  state = {
    loopsRemaining: this.props.maxLoops,
  }
}

그러나 Dan Abramov의 React DnD 모듈 과 같은 일부 공식 예제 는 ES6+를 사용하지만 여전히 생성자 내에서 상태를 정의합니다.

constructor(props) {
    super(props);
    this.moveCard = this.moveCard.bind(this);
    this.state = {
       // state stuff
    }
}

이제 React의 중요한 기여자인 Dan Abramov는 아마도 생성자 외부에서 상태를 정의할 수 있다는 것을 알고 있지만 여전히 생성자 내에서 이를 수행하기로 선택합니다.

그래서 어떤 방법이 더 좋고 왜 그런지 궁금합니다.


개인 취향의 문제라고 생각합니다. 트랜스파일된 출력은 의미론적으로 동일합니다.


클래스 필드 제안 이 생성자 본문 코드에 대한 구문 설탕 이기 때문에 동일 합니다.

명시적 생성자가 필요하지 않은 경우(임시 지역 변수 생성 등) constructor클래스 필드 대신 생략할 수 있습니다.

명시적 생성자의 문제는 super인수( props)가 종종 실수로 생략되어 문제가 발생할 수 있다는 것입니다.

constructor() {
    super();
    this.state = { foo: this.props.foo } // this.props is undefined
}

명시적 생성자는 가독성에 도움이 될 수 있습니다. 방법은 일반적으로 constructor화살표 속성 아래 배치됩니다 . 클래스 필드는 나열된 순서대로 할당되기 때문에 의도한 대로 작동하지 않습니다.

state = { foo: { method: this.someMethod } } // this.someMethod is undefined

someMethod = () => ...;

이 경우 명시적 생성자는 더 읽기 쉬운 코드를 생성할 수 있습니다.

constructor(props) {
    super(props);

    // <-- this is the place where this.someMethod is really assigned

    this.state = { foo: { method: this.someMethod } }
}

someMethod = () => ...;

Dan's code actually has a subtle bug which is why I recommend using the initializers whenever possible. React component constructors take two arguments - props and the context. He's not passing it to the parent constructor and it could easily be missed by some other developer who needed it.

Sometimes you have no choice, like when the initializer depends on the constructor arguments, so just remember to pass all the arguments to the parent.

After trying a few things, looks like React doesn't have the issue I was thinking of. You can pass whatever you want to the parent constructor and it will be fine. E.g.:

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

  render() {
    // this.props will still be set correctly here
  }
}

I still recommend using the initializers as not having to call the parent constructor is one less thing to think about.

ReferenceURL : https://stackoverflow.com/questions/37788342/is-it-better-to-define-state-in-constructor-or-using-property-initializers

반응형