ReactJS : 컴포넌트 초기 상태를 소품으로 전달하는 이유는 무엇입니까?


79

라이브 업데이트를 위해 SocketIO의 도움으로 작은 ReactJS 대시 보드를 만들었습니다. 대시 보드를 업데이트하고 있지만 올바르게 수행했는지 확실하지 않다는 점이 귀찮습니다.

나를 가장 괴롭히는 것은 안티 패턴 게시물 로서 getInitialStateProps입니다 . 페이지를로드하는 것 외에 사용자 상호 작용이 필요하지 않은 서버에서 실시간 업데이트를 가져 오는 대시 보드를 만들었습니다. 내가 읽은 내용 this.state에서 컴포넌트를 다시 렌더링해야하는지 여부를 결정하는 내용이 포함되어야합니다 this.props. 그리고 .... 아직 모르겠습니다.

그러나 처음에를 호출 할 때는 React.render(<MyComponent />, ...)props 만 전달할 수 있습니다. 제 경우에는 서버에서 모든 데이터를 가져 오므로 초기 소품은 this.state어쨌든 끝납니다 . 따라서 내 모든 구성 요소는 다음과 같습니다.

getInitialState: function() {
    return {
        progress: this.props.progress,
        latest_update: this.props.latest_update,
        nearest_center: this.props.nearest_center
    }
}

앞서 언급 한 블로그 게시물을 잘못 해석하지 않는 한 이는 반 패턴입니다. 그러나 나는 컴포넌트에 상태를 주입하는 다른 방법을 보지 못했으며, 모든 props에 레이블을 붙이지 않는 한 그것이 왜 안티 패턴인지 이해하지 못합니다 initial. 이런 건, 내가 느끼는 그건 이제 내가 전에했던 것보다 더 많은 변수 (앞에는 사람들을 추적하기 때문에 안티 패턴 initial과없는 사람).


1
2017 년에 Facebook은 props를 사용하여 문서에서 초기 상태를 설정하는 방법을 보여줍니다. reactjs.org/docs/react-component.html#constructor
Rohmer

1
@Rohmer의 링크에는 대안에 대한 심층 토론과 피해야 할 사항이있는 파생 된 상태가 필요하지 않을 수 있습니다.
ToolmakerSteve

답변:


94

면책 조항 :이 질문에 대답했을 때 나는 바닐라 플럭스를 배우거나 구현하려고 노력하고 있었고 그것에 대해 약간 회의적이었습니다. 나중에 모든 것을 Redux로 마이그레이션했습니다. 따라서 조언 : Redux 또는 MobX를 사용하십시오. 이 질문에 대한 답이 더 이상 필요하지 않을 가능성이 있습니다 (과학 제외).

구성 요소 가 처음 렌더링 될 때만 메서드가 호출 prop되기 때문에 초기 상태를 구성 요소에 전달하는 것은 안티 패턴 getInitialState입니다. 즉, 다른 값을로 전달하는 해당 구성 요소를 다시 렌더링하면 구성 prop요소가 처음 렌더링되었을 때의 상태를 유지하므로 구성 요소가 그에 따라 반응하지 않습니다. 오류가 발생하기 쉽습니다.

그리고 다음과 같이해야합니다.

구성 요소를 가능한 한 상태 비 저장으로 만드십시오. Stateless 구성 요소는 입력을 기반으로 출력 을 렌더링하므로 테스트하기가 더 쉽습니다 . 그렇게 간단합니다.

하지만 헤이 .. 내 구성 요소 데이터가 변경됩니다 .. 상태 비 저장으로 만들 수 없습니다.

네, 대부분 가능합니다. 이를 위해 상태 보유자가 될 외부 구성 요소를 선택합니다. 예제를 사용하여 Dashboard데이터를 포함하는 Widget구성 요소 와 완전히 상태 비 저장 구성 요소를 만들 수 있습니다 . 는 Dashboard모두에게 데이터를 가져 오는 다음 여러 렌더링을 Widgets그들이 통해 필요한 모든 것을받을 props.

하지만 내 위젯에는 상태가 있습니다. 사용자가 구성 할 수 있습니다. 무국적 상태로 만들려면 어떻게해야합니까?

귀하는 Widget, 취급 할 때, 상태에 포함 된 원인 이벤트를 노출 할 수 Dashboard있는 모든이의 원인, 변화에 Widget다시 렌더링 할 수 있습니다. 함수를 수신 Widget함으로써 "이벤트"를 생성 props합니다.

이제 Dashboard가 상태를 유지하지만 초기 상태를 어떻게 전달합니까?

두 가지 옵션이 있습니다. 가장 권장되는 Dashboard getInitialState방법 은 메소드 에서 Ajax 호출 을 수행하여 서버에서 초기 상태를 가져 오는 것입니다. 데이터 관리를위한보다 정교한 방법 인 Flux 를 사용할 수도 있습니다 . Flux는 구현 이라기보다는 패턴에 가깝습니다. 당신의 페이스 북의 구현과 순수 플럭스 사용할 수 있습니다 Dispatcher,하지만 당신은 같은 타사 구현을 사용할 수 있습니다 돌아 오는 , Alt 키 또는 Fluxxor .

또는, 당신은으로이 초기 상태를 전달할 수 있습니다 prop받는 Dashboard명시 적으로 그냥 초기 상태임을 선언 .. 같은 initialData, 예를 들면. 그러나이 경로를 선택하면 첫 번째 렌더링 이후의 상태를 "기억"하기 때문에 다른 초기 상태를 뒤쪽으로 전달할 수 없습니다.

OBS

당신은 당신의 정의가 옳지 않습니다.

상태 는 변경 가능한 데이터, 즉 구성 요소 수명주기 동안 변경 될 데이터를 저장하는 데 사용됩니다. setState메서드를 통해 상태를 변경해야하며 구성 요소가 다시 렌더링됩니다.

소품 은 불변 데이터를 구성 요소에 전달하는 데 사용됩니다. 구성 요소 수명주기 동안 변경되지 않아야합니다. 소품 만 사용하는 구성 요소는 상태 비 저장입니다.

이것은 "구성 요소에 초기 상태를 전달하는 방법"에 대한 관련 소스입니다.


매우 잘 설명되어 있지만 ... 항상 그렇듯이 'but'입니다. 이미지 배열을 가져오고 썸네일 및 onlick 이벤트로 하위 구성 요소를 생성하는 구성 요소가 있으면이 구성 요소에서 큰 이미지를 변경해야합니다. 이미지가 상태가 아니므로 다른 구성 요소를 사용하여 유지할 수 없습니다. 이미지는 로컬이며 큰 이미지로 표시되어야하는 일부 로컬 상태를 관리해야합니다. 상태에서 소품을 사용하고 싶지만 경고 : setState (...) : 기존 상태 전환 동안 업데이트 할 수 없습니다 (예 :) render. Render 메소드는 props와 state의 순수한 기능이어야합니다.
Kania

10
그래서 componentWillReceiveProps(nextProps)상태를 설정 하는 데 사용 하는 것에 대한 의견이 있습니까?
알레한드로

1
componentWillRecieveProps ()는 16.3에서 더 이상 사용되지 않으므로 ... 아니요. 사용하지 마십시오.
Rap

@Alejandro - 당신은 아마 파생 필요하지 않는 상태는 사용의 함정에 대한 깊이있는 설명 (사용되지 않음)입니다 componentWillReceiveProps, 또는 그 (안되지 않음) 교체 getDerivedStateFromProps. 요점 :이 기사에서는 이러한 방법 중 하나를 호출 하지 않는 몇 가지 대안 솔루션을 보여주고 대신 이러한 대안을 사용하는 이유를 설명합니다.
ToolmakerSteve
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.