使用 React Hooks,当我将 prop 从父组件传递到子组件时,子组件中的 prop 未定义
我想做什么?
我想设置一个对象数组,其中数组中的值取决于父组件。
当前尝试执行此操作的代码是什么?
以下是简化的不同文件:
// 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:\Documents\Something",
"Link2": "C:\Documents\SomethingElse"
}
]
}
当我在 Child 组件的
return()
中呈现“filePaths”时,“filePaths”能够呈现,但我希望将“filePaths”设置为变量“links”。
我期望结果是什么?
我希望变量“links”在子组件中可以正常使用,能够在子组件中使用。
实际的结果是什么?结果如何?
启动应用程序时,我收到
TypeError:无法读取未定义的属性“0”。
我认为问题可能是什么?
我认为子组件在父组件未完成
useEffect()
的情况下进行渲染。我想知道是否有办法告诉子组件等待父组件完成,然后继续设置“links”变量。
filePaths
将为
undefined
,因为您使用空输入调用
useState()
。
有两个选项(您可以选择一个)可以解决此问题:
-
在
useState()
内初始化filePaths
-
如果
filePaths
不为 null/undefined,则返回Child
组件。
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}/>}
)
}
我个人更喜欢第二个,因为当
filePaths
仍然为 null/undefined 时,我们可以添加加载组件。
你说得对,这就是你应该更改子组件的原因。无论是否定义,它都会呈现 filePaths 。
尝试按如下方式操作。
export default function Child({filePaths}) {
const [links, setLinks] = useState(filePaths);
useEffect(()=>{
setLinks(filePaths);
},[filePaths])
return (
<div>Nothing here yet, but I would map those links to front-end links.</div>
)
}
我认为你对方法调用顺序的猜测是正确的:
根据 这个 ,当你使用 useEffect 时,该方法会在渲染后被调用,就好像它是一个 componentDidMount 生命周期方法,它受到 React 官方生命周期图 和 React 文档 的支持。这就是因为 Child 组件内的 props.filePaths 未定义的原因。
为了避免这种情况,您应该尝试设置初始值(在 useState 方法中)。
类似于以下内容(可能将重复提取为函数):
// Parent.
export default function Parent() {
var fileContent = JSON.parse(fs.readFileSync("./config.json"); // Reading from a JSON.
var tempFilePaths = [];
fileContent.FilePaths.forEach((file) => {
tempFilePaths.push(file);
});
const [filePaths, setFilePaths] = useState(tempFilePaths);
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}/>
)
}