2016-07-12 16 views
0

그래서 다른 테이블 구성 요소에서 사용할 첫 번째 열로 확인란을 제공하는이 테이블 행 구성 요소를 작성했습니다. 다음은반응 구성 요소가 상위 구성 요소의 상태를 알고 있어야합니까?

표 행 구성 요소의 단순화 된 버전은 다음과 같습니다

import React, { Component, PropTypes } from 'react' 
import { Checkbox } from 'react-bootstrap' 

export default class TableRow extends Component { 
    constructor(props) { 
    super(props) 
    this.handleClickCheckbox = this.handleClickCheckbox.bind(this) 
    } 

    handleClickCheckbox() { 
    this.props.onClickCheckbox(this.props.entity.id) 
    } 

    render() { 
    const { checked, children } = this.props 

    return (
     <tr> 
     <Checkbox 
      checked={checked} 
      onChange={this.handleClickCheckbox} 
     >&nbsp;</Checkbox> 
     {children} 
     </tr> 
    } 

} 
TableRow.propTypes = { 
    entity: PropTypes.shape({ 
    id: PropTypes.number 
    }), 
    checked: PropTypes.bool, 
    onClickCheckbox: PropTypes.func 
} 

테이블 :

확인 소품의 값이 데이터베이스에서 올 수 있기 때문에 내가 체크 박스를 제어 입력을 만들어
import React, { Component, PropTypes } from 'react' 
import { Table } from 'react-bootstrap' 
import TableRow from './TableRow' 

class SampleTable extends Component { 
    constructor(props) { 
    super(props) 
    this.state = { 
     checkedEntitiesIds: [] 
    } 
    this.handleChangeChecked = this.handleChangeChecked.bind(this) 
    } 

    handleChangeChecked(id) { 
    const { checkedEntitiesIds } = this.state 
    const indexOfEntity = checkedEntitiesIds.indexOf(id) 
    // uncheck it if it's already checked, vice versa 
    this.setState({ 
     checkedEntitiesIds : indexOfEntity > -1 ? 
     checkedEntitiesIds.filter((id, index) => index != indexOfEntity) : 
     [...checkedEntitiesIds, id] 
    }) 
    } 

    render() { 
    const { entities } = this.props // can come from either parent component or subcribe to redux state 
    return (
     <Table> 
     <thead> 
      <tr> 
      <th>placeholder for checkbox column</th> 
      <th>dummy header 1</th> 
      <th>dummy header 2</th> 
      </tr> 
     </thead> 
     <tbody> 
     {entities.map(entity => 
      <TableRow 
      key={entity.id} 
      entity={entity} 
      checked={this.state.checkedIds.indexOf(action.id) > -1} 
      onClickCheckbox={this.handleChangeChecked} 
      > 
      <td>dummy table cell 1</td> 
      <td>dummy table cell 2</td> 
      </TableRow> 
     )} 
     </tbody> 
     </Table> 
    ) 
    } 
} 

. 각 테이블 행에는 행을 고유하게 식별 할 수있는 엔티티 props가 있습니다. TableRow 구성 요소에서 checked 상태를 유지하는 것이 아니라 테이블 구성 요소에서 checkedEntitiesIds 상태를 유지합니다. 이는 내가 최대의 유연성을 제공한다고 생각하기 때문입니다.

내 동료 중 한 명은 모든 테이블 구성 요소에서 해당 checkedEntitiesIds 상태와 handleChangeChecked 함수를 유지해야한다는 사실을 좋아하지 않습니다. 그는 checkedEntitiesIds 상태를 TableRow에 추가하고 handleChangeChecked의 함수 본문을 TableRow로 옮기는 제안을했습니다. 작동 방식은 확인란이 클릭/변경 될 때마다입니다. TableRow 내의 checkedEntitiesIds 상태가 먼저 업데이트되고 부모 테이블로 다시 전달되어 부모 구성 요소의 checkedEntitiesIds 상태도 업데이트됩니다. 그런 식으로 그는 check/uncheck 논리를 계속해서 쓸 필요가 없습니다.

여러 가지 일들이 나에게 그러한 변화를 만들기 위해 귀찮게 :

  1. 은 TableRow 만들기를 표 상태로 가정되는 checkedEntitiesIds의 지식을 가지고하는 것은 매우 직관적이다.
  2. 진실의 출처가 중복됩니다.
  3. TableRow에는 상태가 있습니다. 내가 틀렸다면 나를 바로 잡아라. 제 이해는 저급의 벙어리 구성 요소는 거의 자체 상태가 없어야합니다.
  4. 일부 scanerios에서 확인란 클릭 이벤트가 반드시 상태 변경을 초래하지 않을 수도 있습니다. 예를 들어, 확인란을 클릭하면 모달 확인을 먼저 수행하고 예를 선택하는 경우에만 상태를 업데이트합니다. TableRow 내에서 state를 사용하는 것은 그러한 유연성을 제공하지 않습니다.

나는 그의 제안이 다소 반대 패턴이라는 것을 확신합니다. 구성 요소를 두는 방식이 합리적인지, 나열된 점이 유효한지 여부는 확실하지 않습니다. 나는 그를 설득하기 위해 여기에 중요한 것들을 놓치고 있습니까? 재사용 성 측면에서 코드를 개선 할 수있는 방법이 있습니까? 모든 통찰력은 인정 될 것이다.

답변

2

당신이 가져다 준 모든 포인트는 합법적 인 것처럼 보입니다. 스마트 대 멍청한 구성 요소 패턴은 모든 사람이 채택하고있는 것으로 보입니다 (좋은 이유는이 명확한 분리가 없을 때 코드가 정말로 엉망이됩니다).

동료의 제안에 근본적으로 잘못된 또 다른 사항은 자녀에게서 부모로 데이터가 상향 흐름한다는 사실입니다. React의 핵심 아이디어 중 하나는 단방향 데이터 흐름입니다. 부모에게 전파 할 아동의 변경 사항은이 단방향 속성을 유지하기 위해 (또는 데이터 계층이 무엇이든간에) 으로 가게됩니다.아이가 업데이트의 부모에게 통보 갖는

React Data Flow

, 그것은 합병증의 레이어 추가 (영원히 부모에게 돌아갑니다 및 루프 아이의 업데이 트를 트리거 어떤 경우?)를했다 반작용이 처음부터 제거하려고 시도한 것입니다.이 문제로 인해 Angular 응용 프로그램의 확장성에 의문을 제기하고 큰 스케일에서는 너무 복잡해졌습니다.

+1

설명 해 주셔서 감사합니다. 특히 단방향 데이터 흐름 부분에서 많은 도움이됩니다. 나중에 다른 답변을 제출하지 않으면 정답으로 바꿀 것입니다. – aarryy

관련 문제