Development Tip

React 컴포넌트에 강제로 다시 마운트하는 방법은 무엇입니까?

yourdevel 2020. 10. 8. 19:08
반응형

React 컴포넌트에 강제로 다시 마운트하는 방법은 무엇입니까?


조건부 렌더링이있는 뷰 구성 요소가 있다고 가정 해 보겠습니다.

render(){
    if (this.state.employed) {
        return (
            <div>
                <MyInput ref="job-title" name="job-title" />
            </div>
        );
    } else {
        return (
            <div>
                <MyInput ref="unemployment-reason" name="unemployment-reason" />
                <MyInput ref="unemployment-duration" name="unemployment-duration" />
            </div>
        );
    }
}

MyInput은 다음과 같습니다.

class MyInput extends React.Component {

    ...

    render(){
        return (
            <div>
                <input name={this.props.name} 
                    ref="input" 
                    type="text" 
                    value={this.props.value || null}
                    onBlur={this.handleBlur.bind(this)}
                    onChange={this.handleTyping.bind(this)} />
            </div>
        );
    }
}

employed사실 이라고합시다 . false로 전환하고 다른 뷰가 렌더링 될 때마다 만 unemployment-duration다시 초기화됩니다. 또한 unemployment-reasonfrom 값으로 미리 채워 job-title집니다 (조건이 변경되기 전에 값이 제공된 경우).

두 번째 렌더링 루틴의 마크 업을 다음과 같이 변경하면 :

render(){
    if (this.state.employed) {
        return (
            <div>
                <MyInput ref="job-title" name="job-title" />
            </div>
        );
    } else {
        return (
            <div>
                <span>Diff me!</span>
                <MyInput ref="unemployment-reason" name="unemployment-reason" />
                <MyInput ref="unemployment-duration" name="unemployment-duration" />
            </div>
        );
    }
}

모든 것이 잘 작동하는 것 같습니다. React가 '직위'와 '실업 이유'를 구별하지 못하는 것 같습니다.

내가 뭘 잘못하고 있는지 말해줘 ...


아마도 일어나는 일은 React가 렌더링 사이에 하나의 MyInput( unemployment-duration) 추가 되었다고 생각한다는 것 입니다. 따라서 job-title는로 대체되지 않으므로 unemployment-reason미리 정의 된 값이 바뀝니다.

React가 diff를 수행 할 때 key속성 에 따라 어떤 구성 요소가 새로운 구성 요소인지 오래된 구성 요소인지 결정 합니다. 이러한 키가 코드에 제공되지 않으면 자체적으로 생성됩니다.

마지막으로 제공하는 코드 스 니펫이 작동하는 이유는 React가 본질적으로 부모 아래의 모든 요소의 계층 구조를 변경해야하기 때문에 div모든 자식의 다시 렌더링을 트리거 할 것이라고 믿기 때문입니다 (이것이 작동하는 이유입니다). span상단 대신 하단에 추가했다면 이전 요소의 계층 구조가 변경되지 않고 해당 요소가 다시 렌더링되지 않습니다 (문제가 지속됨).

공식 React 문서에 나오는 내용은 다음과 같습니다 .

하위 항목이 (검색 결과에서와 같이) 뒤섞이거나 새 구성 요소가 목록의 맨 앞에 추가되면 (스트림에서와 같이) 상황이 더 복잡해집니다. 렌더 패스에서 각 하위 항목의 ID와 상태를 유지해야하는 경우 키를 할당하여 각 하위 항목을 고유하게 식별 할 수 있습니다.

React가 키가있는 자식을 조정하면 키가있는 자식이 다시 정렬되거나 (재사용 대신) 폐기됩니다.

key부모 div또는 모든 MyInput요소에 고유 한 요소를 직접 제공하여이 문제를 해결할 수 있어야합니다 .

예를 들면 :

render(){
    if (this.state.employed) {
        return (
            <div key="employed">
                <MyInput ref="job-title" name="job-title" />
            </div>
        );
    } else {
        return (
            <div key="notEmployed">
                <MyInput ref="unemployment-reason" name="unemployment-reason" />
                <MyInput ref="unemployment-duration" name="unemployment-duration" />
            </div>
        );
    }
}

또는

render(){
    if (this.state.employed) {
        return (
            <div>
                <MyInput key="title" ref="job-title" name="job-title" />
            </div>
        );
    } else {
        return (
            <div>
                <MyInput key="reason" ref="unemployment-reason" name="unemployment-reason" />
                <MyInput key="duration" ref="unemployment-duration" name="unemployment-duration" />
            </div>
        );
    }
}

Now, when React does the diff, it will see that the divs are different and will re-render it including all of its' children (1st example). In the 2nd example, the diff will be a success on job-title and unemployment-reason since they now have different keys.

You can of course use any keys you want, as long as they are unique.


Update August 2017

For a better insight into how keys work in React, I strongly recommend reading my answer to Understanding unique keys in React.js.


Update November 2017

This update should've been posted a while ago, but using string literals in ref is now deprecated. For example ref="job-title" should now instead be ref={(el) => this.jobTitleRef = el} (for example). See my answer to Deprecation warning using this.refs for more info.


Change the key of the component.

<Component key="1" />
<Component key="2" />

Component will be unmounted and a new instance of Component will be mounted since the key has changed.

edit: Documented on You Probably Don't Need Derived State:

When a key changes, React will create a new component instance rather than update the current one. Keys are usually used for dynamic lists but are also useful here.


Use setState in your view to change employed property of state. This is example of React render engine.

 someFunctionWhichChangeParamEmployed(isEmployed) {
      this.setState({
          employed: isEmployed
      });
 }

 getInitialState() {
      return {
          employed: true
      }
 },

 render(){
    if (this.state.employed) {
        return (
            <div>
                <MyInput ref="job-title" name="job-title" />
            </div>
        );
    } else {
        return (
            <div>
                <span>Diff me!</span>
                <MyInput ref="unemployment-reason" name="unemployment-reason" />
                <MyInput ref="unemployment-duration" name="unemployment-duration" />
            </div>
        );
    }
}

참고URL : https://stackoverflow.com/questions/35792275/how-to-force-remounting-on-react-components

반응형