2

I am trying to create a dynamic table, using this example- Dynamic & Complex rowspan in HTML table

I am trying to replicate the similar thing in react.js

I have put a closing tr tag in conditional rendering if the index is 0. However, it gives me ' Expected corresponding JSX closing tag for <>'

The state 'data' object which I got from back-end is something like -

{
  "100": [
    "ABC"
  ],
  "101": [
    "123",
    "DEF",
    "XYZ",
    "456",
    "657",
    "1234",
    "4564",
    "vdfgx",
    "vcegefgg",
    "g544"
  ]
}

I have written following code in component to create dynamic table.

<table>
    <thead>
        <tr>
            <th>Code</th>
            <th>Reason</th>
        </tr>
    </thead>
    <tbody>
        {Object.keys(this.state.data).map(
            (error_code, i) => {
                return (
                    <React.Fragment>
                        <tr> 
                            <td
                                rowSpan={
                                    this.state.data[
                                        error_code
                                    ].length
                                }
                                key={i}
                            >
                                {error_code}
                            </td>
                            {this.state.data[
                                error_code
                            ].map((error_description, index) => (
                                <React.Fragment>
                                    {index === 0 ? (
                                        <React.Fragment>
                                            <td
                                                key={index}
                                                rowSpan="1"
                                            >
                                                {error_description}
                                            </td>
                                            </tr>                //<---  HERE
                                        </React.Fragment>
                                    ) : (
                                        <tr>
                                            <td
                                                key={index}
                                                rowSpan="1"
                                            >
                                                {error_description}
                                            </td>
                                        </tr>
                                    )}
                                </React.Fragment>
                            ))}
                    </React.Fragment>
                );
            }
        )}
    </tbody>
</table>

I want the final output something like -

   <tbody>
    <tr>
        <td rowspan="1">100</td>
        <td rowspan="1">ABC</td>

    </tr>
    <tr>
        <td rowspan="10">101</td>
        <td rowspan="1">123</td>
    </tr>
    <tr>
        <td rowspan="1">DEF</td>
    </tr>
    <tr>
        <td rowspan="1">XYZ</td>
    </tr>
    <tr>
        <td rowspan="1">456</td>
    </tr>
    .....

   </tbody>

Could anyone please guide me the correct way to achieve the desired output ?

2 Answers 2

4

JSX, like XML, requires proper nesting <><tr>...</tr></> and does not support overlapping tags like <><tr></></tr>. You need to structure your code in a way to preserve proper nesting:

  <tbody>
    {Object.keys(this.state.data).map((error_code, i) => {
      return this.state.data[error_code].map((error_description, index) =>
        index === 0 ? (
          <tr>
            <td rowSpan={this.state.data[error_code].length} key={i}>
              {error_code}
            </td>
            <td key={index} rowSpan="1">
              {error_description}
            </td>
          </tr>
        ) : (
          <tr>
            <td key={index} rowSpan="1">
              {error_description}
            </td>
          </tr>
        )
      )
    })}
  </tbody>
Sign up to request clarification or add additional context in comments.

Comments

1

JSX does not generate a string. It generates a tree-like structure built out of function calls and Objects. Any <tag></tag> translates into a function call, that's why your code is invalid. You need to rethink this component. Split the data processing and decision making into a separate function that does only that and returns the final data to be rendered. Then loop/map through it in render and return the elements structure.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.