What am I trying to do?
I’m trying to set an array of objects in which the value within the array is dependent on the parent component.
What is the code that currently tries to do that?
Here are the different files simplified:
// Parent. export default function Parent() { const [filePaths, setFilePaths] = useState(); useEffect(() => { var fileContent = JSON.parse(fs.readFileSync("./config.json"); // Reading from a JSON. var tempFilePaths = []; fileContent.FilePaths.forEach((file) => { tempFilePaths.push(file); }); setFilePaths(tempFilePaths); // Contents of "config.js" is now in the "useState". }, []); return ( <Child filePaths={filePaths}/> ) }
// Child. export default function Child({filePaths}) { var links = [ { path: filePaths[0].Link1, }, { path: filePaths[0].Link2, }, ] return ( <div>Nothing here yet, but I would map those links to front-end links.</div> ) }
// config.json { "url": "http:localhost:3000", "FilePaths": [ { "Link1": "C:DocumentsSomething", "Link2": "C:DocumentsSomethingElse" } ] }
When I render the “filePaths” in the return()
of the Child component, the “filePaths” is able to be rendered, but I wish to set the “filePaths” to the variable “links”.
What do I expect the result to be?
I expect the variable “links” to be fine in the child component, being able to be used within the child component.
What is the actual result?
When starting the app I get a TypeError: Cannot read property '0' of undefined.
What I think the problem could be?
I think the child component renders without the parent component finishing the useEffect()
. I’m wondering if there’s a way to tell the child component to wait for the parent component to finish, then proceed with setting the variable of “links”.
Advertisement
Answer
filePaths
will be undefined
because you call useState()
with empty input.
There are two options (you can choose one) to solve this:
Initialize
filePaths
inside theuseState()
Return the
Child
component if thefilePaths
is not null/undefined.
export default function Parent() { const [filePaths, setFilePaths] = useState(); useEffect(() => { var fileContent = JSON.parse(fs.readFileSync("./config.json"); // Reading from a JSON. var tempFilePaths = []; fileContent.FilePaths.forEach((file) => { tempFilePaths.push(file); }); setFilePaths(tempFilePaths); // Contents of "config.js" is now in the "useState". }, []); return ( // return the Child component if the filePaths is not null/undefined {filePaths && <Child filePaths={filePaths}/>} ) }
I personally prefer the second one because we can add a loading component when the filePaths
is still null/undefined.