Reputation: 732
I have to build something between tree and table. I have folder, subfolders and elements. There is one folder, which keeps inside all subfolders. Informations rendering correctly, but react is ignoring part of my code.
const Folder = (props) => {
return (
<tr key={props.id}>
<td className='w1_20'><input type='checkbox'/></td>
<td className='w1_10'>{props.id}</td>
<td className='w5_10'><a href=''>{props.name}</a></td>
<td className='w2_10'/>
<td className='w3_20'/>
</tr>
)
};
This is my folder component.
const Subfolder = (props) => {
return (
<tr>
<td className='p-0 bt-0' colSpan='5'>
<table className='table table-hover w-100'>
<tbody>
{props.children}
</tbody>
</table>
</td>
</tr>
)
};
This is my subfolder component.
const Segment = (props) => {
return (
<tr key={props.element.id}>
<td className='w1_20'><input type='checkbox'/></td>
<td className='w1_10'>{props.element.id}</td>
<td className='w5_10'>{props.element.name}</td>
<td className='w2_10'>{props.element.value}</td>
<td className='w3_20'/>
</tr>
)
};
This is element.
The structure should looks like:
Each subfolder should be next row after the folder row and it contains table inside (this is really important, as later I need to be able to manipulate these tables). Inside subfolders, can be element rows or another subfolder.
I know, that subfolders should have key also, but the major problem for me now is that React completely ignore, that inside subfolder td element I'm using another table with props children.
return (
<tbody>
<Folder id={1} name="Folder" />
<Subfolder>
<Subfolder>
<Segment segment={{id: 1, name: "Element"}}/>
</Subfolder>
</Subfolder>
</tbody>
);
If I try to use it this way, it works fine. But to parse my API response I have function, where I push each element inside array, which I return at the end.
const InitTable = (props) => {
let table = [];
const mapResponse = (data) => {
if (data) {
if (data['folder']) {
table = [...table, <Folder key={data.folder.id} id={data.folder.id} name={data.folder.name}/>];
let sf = data['children'].map((item) => {
if (item) {
return mapResponse(item);
}
});
table = [...table, <Subfolder>{sf}</Subfolder>];
} else if (data['segment']) {
if (data['statistics']) {
table = [...table, <Segment statistics={data['statistics']} segment={data['segment']}/>];
}
}
}
};
if (props.segments) {
mapResponse(props.segments.root);
}
return (
<tbody>
{table}
</tbody>
);
};
I need to create chunk of JSX and render at the end, so i check type of each object in the API response and push different component to the array. The main problem is that then, React completely ignore my tables inside td elements are render all as regular table.
When I'm expecting something more like:
I know the easiest way is to build it as normal string and later use dangerouslySetInnerHTML() method, but I want to avoid it.
Upvotes: 1
Views: 2814
Reputation: 7407
It seems like there are 2 issues
<Segment segment={{id: 1, name: "Element"}}/>
takes a element
prop, but your passing it a segment
You method for creating the main tbody
is adding to the same array instead of returning a new one.
const InitTable = props => {
const mapResponse = data => {
if (data) {
if (data['folder']) {
let sf = data['children'].map(item => {
if (item) {
return mapResponse(item);
}
});
return [
<Folder
key={data.folder.id}
id={data.folder.id}
name={data.folder.name}
/>,
<Subfolder>{sf}</Subfolder>,
];
} else if (data['segment']) {
if (data['statistics']) {
return [
<Segment
statistics={data['statistics']}
element={data['segment']}
/>,
];
}
}
}
};
return (
<tbody>
{mapResponse(props.segments.root)}
</tbody>
);
};
https://codesandbox.io/s/gJJ2Lm2vD
Upvotes: 1