2016-07-01 2 views
2

면책 조항 : 나는 Reactjs: how to modify child state or props from parent?을보고 내 질문에 맞는 답을 찾지 못했다.ReactJS : 부모로부터 소품을 통해 부모 자식 상태로 변이

그래서 상태에 따라 다른 DOM을 렌더링하는 재사용 가능한 상태 저장 대화 구성 요소가 있습니다. 부모로부터 렌더링되는 DOM을 제어 할 수 있어야합니다.

TL - 부모로부터 하위 구성 요소 상태를 돌연변이해야합니까? 그렇다면 다른 옵션은 무엇입니까?

아동 :

export default class Conversation extends Component { 
 
    constructor(props) { 
 
    super(props); 
 
    
 
    this.state = { 
 
     newConversation: props.showNewConversation 
 
    }; 
 
    } 
 
    
 
    render() { 
 
    if (!this.state.newConversation) { 
 
    return (
 
     <div>Current Conversation</div> 
 
    ); 
 
    } return (
 
     <div>New Conversation</div> 
 
    ); 
 
    } 
 
}

가 지금은 여러 곳에서이 구성 요소를 렌더링 할 필요가 있지만 적절한 DOM은 당신이 할 수있는 네비게이션 바에서 즉, 부모에 따라 렌더링 할 필요가 새로운 대화를 만들고, 사용자 페이지에서 대화를 직접 할 수 있으므로, 내가 소품을 통해 아이에게 전화 할 때 제어 할 수 있습니다. 아이를 호출하고 소품을 통해 상태를 설정

는 :

<Conversation 
 
    showNewConversation={this.state.isConversationShown === true} 
 
/>

이, 내 질문에 사실은 왜 현재 작업,하지만이 반응에서 아주 나쁜 방법입니다 들었다된다 이것은 나쁜 습관으로 여겨지며 좋은 연습 해결책은 어떻게 생겼을까요?

+0

이 데이터에 대한 아주 나쁜 관행이 왜 소유의에 소유자 흐름 : 당신이 절대적으로 상태를 변경해야합니다, 그것은 부모에 의해 소품의 변화의 형태로 할 필요가있는 경우

구성 요소를 통해 '소품'? –

답변

4

React에서 가능한 가장 좋은 방법은 'state-less'만큼의 구성 요소를 만드는 것입니다. 일반적으로 비동기 데이터를로드하지 않거나 사용자 입력을 수락하는 경우에는 상태가 필요하지 않습니다. 다음과 같이

이 예에서 주요 문제는 발생 : 부모가 그런 아이 반응으로 예상대로 렌더링되지 않습니다

<Conversation newConversation={false} /> 

에 rerenders 그것은 나중에

<Conversation newConversation={true} /> 

그리고 렌더링하는 경우 것 ' 자식 대화 (다시 렌더링)를 업데이트하지만 생성자를 다시 호출하지 않습니다. 당신은 생성자의 상태로만 소품을 전송했기 때문에, 자식은 절대로 바뀌지 않을 것입니다.

대신 대부분의 구성 요소는 해당 속성의 함수로만 렌더링해야합니다. 당신의 아이는 다음에 적용 할 수 있습니다 :

export default class Conversation extends Component { 
    constructor(props) { 
    super(props); 
    } 

    render() { 
    if (!this.props.newConversation) { 
    return (
     <div>Current Conversation</div> 
    ); 
    } return (
     <div>New Conversation</div> 
    ); 
    } 
} 

여기에서, 부모에 의해 업데이트가 직접 아이의 렌더링() 함수에서 소품을 참조하기 때문에 아이가 올바르게 다시 렌더링 할 수 있습니다.

대화에 대한 데이터가 더 많이있는 경우 모든 데이터를 소품으로 전달해야합니다. 즉

<Conversation conversationData={{name: 'abc', new: false}} /> 

그런 다음 대화 구성 요소는 render() 메소드에서 직접 소품에 액세스 할 수 있습니다.

export default class Conversation extends Component { 
    constructor(props) { 
    super(props); 

    this.state = { 
     newConversation: props.showNewConversation 
    }; 
    } 

    // Response to change 
    componentWillReceiveProps(nextProps){ 
     this.setState({newConversation: this.props.showNewConversation}); 

    } 

    render() { 
    if (!this.state.newConversation) { 
    return (
     <div>Current Conversation</div> 
    ); 
    } return (
     <div>New Conversation</div> 
    ); 
    } 
} 
+0

굉장한 답변! 주에서 그것을 꺼내고 대화에서 소품으로 만 집어 넣으면 대접을 받았고 훨씬 더 깨끗합니다. 고마워요! –

관련 문제