I have a nested dictionary with the structure { "1" : [{"a" : ["p", "q"]}, "b", "c", {"d" : ["h", "w"]}] }
. Here is the link to the exact data. The depth can go up to any length, but the dept is finite. I am trying to create a nested list (of checkboxes) with the following code.
import React from "react";
class TagTree extends React.Component{
render(){
return(
<React.Fragment>
<ul>
{
this.props.tag.map( (t) =>
<li>
{ (typeof(t) === "object")? Object.keys(t) : t }
</li>
)
}
</ul>
</React.Fragment>
)
}
}
class TagApp extends React.Component{
render(){
return(
<div>
<TagTree tag={this.props.tagList} />
</div>
)
}
}
export default TagApp;
Here, the input dictionary is passed as this.props.tagList
. I have two problems.
- If I recursively create
TagTree
at the following line
<li>
{ (typeof(t) === "object")? <TagTree tag={t} /> : t }
</li>
I get an error
- I need to display the key before displaying it's contents.
My thanks for your help. The error is as follows.
Unchecked runtime.lastError: The message port closed before a response was received.
localhost/:1 Unchecked runtime.lastError: The message port closed before a response was received.
localhost/:1 Unchecked runtime.lastError: The message port closed before a response was received.
localhost/:1 Unchecked runtime.lastError: The message port closed before a response was received.
react-jsx-dev-runtime.development.js:87 Warning: Each child in a list should have a unique "key" prop.
Check the render method of `TagTree`. See https://reactjs.org/link/warning-keys for more information.
at li
at TagTree (http://localhost:3000/static/js/bundle.js:1301:1)
at div
at TagApp (http://localhost:3000/static/js/bundle.js:1330:1)
at div
at div
at McqApp (http://localhost:3000/static/js/bundle.js:952:5)
at App (http://localhost:3000/static/js/bundle.js:32:1)
printWarning @ react-jsx-dev-runtime.development.js:87
error @ react-jsx-dev-runtime.development.js:61
validateExplicitKey @ react-jsx-dev-runtime.development.js:1078
validateChildKeys @ react-jsx-dev-runtime.development.js:1105
jsxWithValidation @ react-jsx-dev-runtime.development.js:1276
render @ tag.jsx:7
finishClassComponent @ react-dom.development.js:19752
updateClassComponent @ react-dom.development.js:19698
beginWork @ react-dom.development.js:21611
beginWork$1 @ react-dom.development.js:27426
performUnitOfWork @ react-dom.development.js:26557
workLoopSync @ react-dom.development.js:26466
renderRootSync @ react-dom.development.js:26434
performConcurrentWorkOnRoot @ react-dom.development.js:25738
workLoop @ scheduler.development.js:266
flushWork @ scheduler.development.js:239
performWorkUntilDeadline @ scheduler.development.js:533
6tag.jsx:8 Uncaught TypeError: this.props.tag.map is not a function
at TagTree.render (tag.jsx:8:1)
at finishClassComponent (react-dom.development.js:19752:1)
at updateClassComponent (react-dom.development.js:19698:1)
at beginWork (react-dom.development.js:21611:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at beginWork$1 (react-dom.development.js:27451:1)
at performUnitOfWork (react-dom.development.js:26557:1)
at workLoopSync (react-dom.development.js:26466:1)
render @ tag.jsx:8
finishClassComponent @ react-dom.development.js:19752
updateClassComponent @ react-dom.development.js:19698
beginWork @ react-dom.development.js:21611
callCallback @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
beginWork$1 @ react-dom.development.js:27451
performUnitOfWork @ react-dom.development.js:26557
workLoopSync @ react-dom.development.js:26466
renderRootSync @ react-dom.development.js:26434
performConcurrentWorkOnRoot @ react-dom.development.js:25738
workLoop @ scheduler.development.js:266
flushWork @ scheduler.development.js:239
performWorkUntilDeadline @ scheduler.development.js:533
6tag.jsx:8 Uncaught TypeError: this.props.tag.map is not a function
at TagTree.render (tag.jsx:8:1)
at finishClassComponent (react-dom.development.js:19752:1)
at updateClassComponent (react-dom.development.js:19698:1)
at beginWork (react-dom.development.js:21611:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at beginWork$1 (react-dom.development.js:27451:1)
at performUnitOfWork (react-dom.development.js:26557:1)
at workLoopSync (react-dom.development.js:26466:1)
render @ tag.jsx:8
finishClassComponent @ react-dom.development.js:19752
updateClassComponent @ react-dom.development.js:19698
beginWork @ react-dom.development.js:21611
callCallback @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
beginWork$1 @ react-dom.development.js:27451
performUnitOfWork @ react-dom.development.js:26557
workLoopSync @ react-dom.development.js:26466
renderRootSync @ react-dom.development.js:26434
recoverFromConcurrentError @ react-dom.development.js:25850
performConcurrentWorkOnRoot @ react-dom.development.js:25750
workLoop @ scheduler.development.js:266
flushWork @ scheduler.development.js:239
performWorkUntilDeadline @ scheduler.development.js:533
6react-dom.development.js:18687 The above error occurred in the <TagTree> component:
at TagTree (http://localhost:3000/static/js/bundle.js:1301:1)
at li
at ul
at TagTree (http://localhost:3000/static/js/bundle.js:1301:1)
at div
at TagApp (http://localhost:3000/static/js/bundle.js:1330:1)
at div
at div
at McqApp (http://localhost:3000/static/js/bundle.js:952:5)
at App (http://localhost:3000/static/js/bundle.js:32:1)
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
logCapturedError @ react-dom.development.js:18687
update.callback @ react-dom.development.js:18720
callCallback @ react-dom.development.js:13923
commitUpdateQueue @ react-dom.development.js:13944
commitLayoutEffectOnFiber @ react-dom.development.js:23391
commitLayoutMountEffects_complete @ react-dom.development.js:24688
commitLayoutEffects_begin @ react-dom.development.js:24674
commitLayoutEffects @ react-dom.development.js:24612
commitRootImpl @ react-dom.development.js:26823
commitRoot @ react-dom.development.js:26682
finishConcurrentRender @ react-dom.development.js:25892
performConcurrentWorkOnRoot @ react-dom.development.js:25809
workLoop @ scheduler.development.js:266
flushWork @ scheduler.development.js:239
performWorkUntilDeadline @ scheduler.development.js:533
tag.jsx:8 Uncaught TypeError: this.props.tag.map is not a function
at TagTree.render (tag.jsx:8:1)
at finishClassComponent (react-dom.development.js:19752:1)
at updateClassComponent (react-dom.development.js:19698:1)
at beginWork (react-dom.development.js:21611:1)
at beginWork$1 (react-dom.development.js:27426:1)
at performUnitOfWork (react-dom.development.js:26557:1)
at workLoopSync (react-dom.development.js:26466:1)
at renderRootSync (react-dom.development.js:26434:1)
at recoverFromConcurrentError (react-dom.development.js:25850:1)
at performConcurrentWorkOnRoot (react-dom.development.js:25750:1)
CodePudding user response:
{
this.props.tag.map( (t) =>
<li key={typeof(t) === "object" ? Object.keys(t)[0] : t}>
{ (typeof(t) === "object")? <TagTree tag={t} /> : t }
</li>
)
}
CodePudding user response:
I suggest using a list of objects with fixed keys. For example, each objects could look something like this
courses = [
{
"name": "Algebra",
"topics": [
{
"name": "Matrices",
"topics": [
// ...
]
},
// ...
]
},
// ...
]
Now recursively descending into this is much easier because every object will always have a "name"
and "topics"
.