itsource

JSX에서 맵을 포함한 네스트 루프를 갖는 방법은 무엇입니까?

mycopycode 2023. 4. 2. 10:25
반응형

JSX에서 맵을 포함한 네스트 루프를 갖는 방법은 무엇입니까?

두 개의 네스트(nested)를 가질 수 없습니다.map:

render() {
    return (
      <table className="table">
        <tbody>
          {Object.keys(this.state.templates).map(function(template_name) {
            return (
              <tr key={template_name}><td><b>Template: {template_name}</b></td></tr>

              {this.state.templates[template_name].items.map(function(item) {
                return (
                  <tr key={item.id}><td>{item.id}</td></tr>
                )
              })}
            )
          })}
        </tbody>
      </table>
    )
  }

이것으로, 을 알 수 있습니다.SyntaxError: unknown: Unexpected token.

어떻게 둥지를 틀지?map콜은 JSX에 있나요?

요소 안에 싸야 합니다.

뭐 이런 거 (여기에 추가했습니다)tr테이블 요소의 규칙으로 인해):

  render() {
    return (
      <table className="table">
        <tbody>
          {Object.keys(templates).map(function (template_name) {
            return (
              <tr key={template_name}>
                <tr>
                  <td>
                    <b>Template: {template_name}</b>
                  </td>
                </tr>
                {templates[template_name].items.map(function (item) {
                  return (
                    <tr key={item.id}>
                      <td>{item}</td>
                    </tr>
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
    );
  }
}

실행 예(테이블 없음):

const templates = {
  template1: {
    items: [1, 2]
  },
  template2: {
    items: [2, 3, 4]
  },
};

const App = () => (
  <div>
    {
      Object.keys(templates).map(template_name => {
        return (
          <div>
            <div>{template_name}</div>
            {
              templates[template_name].items.map(item => {
                return(<div>{item}</div>)
              })
            }
          </div>
        )
      })
    }
  </div>
);
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

네스트된 지도 기능을 작동시키기 위해 잠시 애를 썼지만whatreturn매우 중요합니다.최종 예상 출력뿐만 아니라 두 번째 맵 자체를 반환해야 합니다.

let { categories } = data;

categories = categories.map(category =>
    category.subcategories.map((subcategory, i) => <h2 key={i}>{subcategory.name}</h2>)
);

return (
    <div className="category-container">
        <div>{categories}</div>
    </div>
);

기술적으로 정확한지 확실하지 않지만, 니모닉으로서 "반환되는 모든 JSX 요소는 하나의 JSX 요소여야 합니다."라는 것을 기억할 수 있습니다.

따라서 대부분의 경우 한 쌍(또는 다른 임의의 태그 쌍)으로 포장하는 것만으로 문제가 해결됩니다.예를 들어, 두 개를 반환하는 경우<div>단, 이 두 개를 컴포넌트의 렌더 방식에서 추출한 것은 틀립니다.<></>쌍으로, 아마 수정될 것입니다.

다만, 예를 들면, 2개의 ES6 맵을 서로 네스트 하는 경우 등, 조금 더 애매한 경우가 있습니다.

<tbody>
{
  this.categorizedData.map(
    (catgGroup) => (
      <tr>
        <td>{catgGroup}</td>
      </tr>
      this.categorizedData[catgGroup].map(
        (item) => (
          <tr>
            <td>{item.name}</td>
            <td>{item.price}</td>
          </tr>
        )
      )
    )
  )
}
</tbody>

다음과 같이 고정할 수 있습니다.

<tbody>
{
  this.categorizedData.map(
    (catgGroup) => (
      <> // <--- Notice this, it will wrap all JSX elements below in one single JSX element.
        <tr>
          <td>{catgGroup}</td>
        </tr>
        {this.categorizedData[catgGroup].map( // <--- Also notice here, we have wrapped it in curly braces, because it is an "expression" inside JSX.
          (item) => (
            <tr>
              <td>{item.name}</td>
              <td>{item.price}</td>
            </tr>
          )
        )}
      </>
    )
  )
}
</tbody>

추신: (문서부터):React 컴포넌트에서 요소의 배열을 반환할 수도 있습니다.

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :slight_smile:
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

문제는 리턴 타입이 React16의 객체가 아닌 배열이어야 한다는 것입니다.다음과 같이 시도할 수 있습니다.

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      templates: {
        foo: {
          items: [
            {id: 0},{id:1}
          ]
        },
        bar: {
          items: [
            {id: 2},{id:3}
          ]
        }
      }
    }
  }
  
  renderTemplate = (template, name) => {
    let data = []
    data = template.items
    data.unshift({ name: name })
    return data.map((item, index) => <tr key={index}><td>{item.name ? item.name : item.id}</td></tr>)
  }
  
  render() {
    return (
      <table>
        <tbody>
          {Object.keys(this.state.templates).map(name => {
            return this.renderTemplate(this.state.templates[name], name)
          })}
        </tbody>
      </table>
    )
  }
}



ReactDOM.render(<App />, document.getElementById('root'))
td {
  color: white;
  padding: 0 20px;
  background: grey;
}
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.1.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.1.1/umd/react-dom.production.min.js"></script>

언급URL : https://stackoverflow.com/questions/47402365/how-to-have-nested-loops-with-map-in-jsx

반응형