programing

여러 테이블 행을 반환하는 React 컴포넌트를 래핑하여 "가 의 자녀로 표시되지 않도록 하려면 어떻게 해야 합니까?여러 테이블 행을 반환하는 React 컴포넌트를 래핑하여 "가 의 자녀로 표시되..

golfzon 2023. 3. 5. 10:52
반응형

여러 테이블 행을 반환하는 React 컴포넌트를 래핑하여 "가 의 자녀로 표시되지 않도록 하려면 어떻게 해야 합니까?
" 오류?

OrderItem이라는 컴포넌트가 있습니다.이 컴포넌트는 오브젝트 안에 여러 개의 오브젝트(최소2개)가 있는 오브젝트를 테이블 내에 여러 행으로 렌더링합니다.테이블 안에는 여러 OrderItem 컴포넌트가 있습니다.문제는 컴포넌트의 렌더 기능에서 여러 줄을 반환할 수 없다는 것입니다.부품은 1개만 반송할 수 있고, div로 포장하면 "라고 적혀 있습니다.<tr>의 아이로 등장할 수 없다<div>"

코드는 다음과 같습니다(가독성을 높이기 위해 몇 가지를 생략했습니다).

Parent() {
  render() {
    return (
      <table>
        <tbody>
          {
            _.map(this.state.orderItems, (value, key) => {
              return <OrderItem value={value} myKey={key}/>
            })
          }
        </tbody>
      </table>
    )
  }
}

class OrderItem extends React.Component {
  render() {
    return (
      <div> // <-- problematic div
        <tr key={this.props.myKey}>
          <td> Table {this.props.value[0].table}</td>
          <td> Item </td>
          <td> Option </td>
        </tr>
        {this.props.value.map((item, index) => {
          if (index > 0) { // skip the first element since it's already used above
            return (
              <tr key={this.props.myKey + index.toString()}>
                <td><img src={item.image} alt={item.name} width="50"/> {item.name}</td>
                <td>{item.selectedOption}</td>
              </tr>
            )
          }
        })}
      </div>
    )
  }
}

여러 행을 div로 감싸지 않고 같은 테이블에 둘 수 있는 방법이 있습니까?각 컴포넌트에 대해 별도의 테이블을 만들 수 있다는 것은 알고 있지만, 그 때문에 포맷이 다소 혼란스러워집니다.

React 16이제 구조하러 왔으니React.Fragment요소 목록을 상위 요소로 줄 바꿈하지 않고 렌더링합니다.다음과 같은 작업을 수행할 수 있습니다.

render() {
  return (
    <React.Fragment>
      <tr>
        ...
      </tr>
    </React.Fragment>
  );
}

Yes!! 테이블 내의 여러 테이블 행에 항목을 매핑할 수 있습니다.콘솔 오류를 발생시키지 않고 실제로 의미론적으로 올바른 솔루션은tbody요소를 루트 구성요소로 지정하고 필요한 수의 행으로 채웁니다.

items.map(item => (
   <tbody>
       <tr>...</tr>
       <tr>...</tr>
   </tbody>
))

다음 게시물에서는 이에 대한 윤리적 질문에 대해 설명하고 여러 개를 사용할 수 있는 이유를 설명합니다.tbody<테이블>에 여러 개의 <tbody> 요소를 포함할 수 있습니까?

한 가지 방법은 분할하는 것입니다.OrderItem렌더링 로직을 메서드로 이동하기 위해 두 개의 컴포넌트로 구성Parent.renderOrderItems:

class Parent extends React.Component {
  renderOrderItems() {
    const rows = []
    for (let orderItem of this.state.orderItems) {
      const values = orderItem.value.slice(0)
      const headerValue = values.shift()
      rows.push(
        <OrderItemHeaderRow table={headerValue.table} key={orderItem.key} />
      )
      values.forEach((item, index) => {
        rows.push(
          <OrderItemRow item={item} key={orderItem.key + index.toString()} />
        )
      })
    }
    return rows
  }
  render() {
    return (
      <table>
        <tbody>
          { this.renderOrderItems() }
        </tbody>
      </table>
    )
  }
}

class OrderItemHeaderRow extends React.Component {
  render() {
    return (
      <tr>
        <td> Table {this.props.table}</td>
        <td> Item </td>
        <td> Option </td>
      </tr>
    )
  }
}

class OrderItemRow extends React.Component {
  render() {
    const { item } = this.props
    return (
      <tr>
        <td>
          <img src={item.image} alt={item.name} width="50"/>
          {item.name}
        </td>
        <td>
          {item.selectedOption}
        </td>
      </tr>
    )
  }
}

깔끔하게 포장하는 방법은 없는 것 같습니다.따라서 테이블 전체를 컴포넌트에 넣고 테이블만 여러 개 배치하여 포맷을 결정하는 것이 더 쉬운 방법입니다.

Parent() {
   render() {
       return (
           {_.map(this.state.orderItems, (value, key) => {
               return <OrderItem value={value} myKey={key} key={key}/>
           })}
       )
   }
}


class OrderItem extends React.Component {
    render() {
        return (
            <table>
                <tbody>
                   <tr>
                       <td> Table {this.props.value[0].table}</td>
                       <td> Item </td>
                       <td> Option </td>
                    </tr>
                    {this.props.value.map((item, index) => {
                        if (index > 0) { // skip the first element since it's already used above
                            return (
                                <tr key={this.props.myKey + index.toString()}>
                                    <td> <img src={item.image} alt={item.name} width="50"/> {item.name}</td>  
                                    <td>{item.selectedOption}</td>
                                </tr>
                            )
                        }
                    })}
                </tbody>
            </table>
        )
    }
}

오래된 질문이지만, 아마 누군가가 더듬거릴지도 모른다.아직 코멘트는 할 수 없기 때문에 @trevorgk의 답변에 조금 더 추가하겠습니다.

이를 사용하여 항목당 여러 행이 있는 테이블(약 1000개의 항목에서 15개의 열로 약 2000개의 행이 생성됨)을 렌더링했는데 Firefox에서 57개의 열에서도 성능이 크게 저하되었습니다.

각 아이템을 렌더링하는 순수한 컴포넌트(각 아이템에 2행씩 1개씩 포함)와 각 아이템에는 체크박스가 붙어 있습니다.

이 체크박스를 클릭하면 Firefox가 업데이트되는 데 10초 이상 걸렸습니다.단, 실제로는 컴포넌트가 순수하기 때문에 한 항목만 업데이트되었습니다.크롬 업데이트는 길게는 0.5초 정도 걸렸다.

리액트 16으로 바꿨는데 차이가 없어요.그리고 새로운 AWESME을 사용했습니다!!!컴포넌트의 렌더 함수에서 어레이를 반환하고 1000개의 <tbody> 요소를 제거하는 기능입니다.Chrome의 성능은 거의 같았지만 Firefox의 업데이트는 0.5초로 "스카이 로켓"되었습니다(Chrome과 인식되는 차이는 없습니다).

이 경우 솔루션은 fragment가 아닌 어레이를 반환하는 것이었습니다.

    return [
        <TrHeader />,
        <TrRows />
    ];

언급URL : https://stackoverflow.com/questions/37982842/how-do-i-wrap-a-react-component-that-returns-multiple-table-rows-and-avoid-the

반응형