简体   繁体   English

使用 React Hooks,当我将 prop 从父组件传递给子组件时,子组件中的 prop 未定义

[英]Using React Hooks, when I pass down a prop from parent to a child component, the prop in the child component is undefined

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:\Documents\Something",
      "Link2": "C:\Documents\SomethingElse"
    }
  ]
}

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".当我在 Child 组件的return()中呈现“filePaths”时,可以呈现“filePaths”,但我希望将“filePaths”设置为变量“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.启动应用程序时,我收到一个类型错误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() .我认为子组件在没有父组件完成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".我想知道是否有办法告诉子组件等待父组件完成,然后继续设置“链接”变量。

filePaths will be undefined because you call useState() with empty input. filePaths将是undefined因为您使用空输入调用useState()

There are two options (you can choose one) to solve this:有两个选项(您可以选择一个)来解决这个问题:

  1. Initialize filePaths inside the useState()useState()初始化filePaths

  2. Return the Child component if the filePaths is not null/undefined.如果filePaths不为空/未定义,则返回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}/>}
    )
}

I personally prefer the second one because we can add a loading component when the filePaths is still null/undefined.我个人更喜欢第二个,因为我们可以在filePaths仍然为空/未定义时添加加载组件。

I think you're right on your guess about the sequence of methods calling:我认为您对方法调用顺序的猜测是正确的:

According to this , when you use useEffect the method gets called after the rendering, as if it was a componentDidMount lifecycle method, which is supported by the React official lifecycle diagram and React Documentation .根据,当您使用useEffect的方法获取与呈现后调用,就好像它是一个componentDidMount生命周期的方法,这是由支持 阵营正式生命周期图作出反应的文档 And that is the reason because the props.filePaths whithin the Child component is undefined.这就是因为 Child 组件中的 props.filePaths 未定义的原因。

To avoid this, you should try to set an initial value (in the useState method).为了避免这种情况,您应该尝试设置一个初始值(在 useState 方法中)。

something like the following (maybe extracting the repetition as a function):类似于以下内容(可能将重复提取为函数):

// 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}/>
  )
}

You are right, that's why you should change your child component.你是对的,这就是为什么你应该改变你的子组件。 It renders the filePaths whether it is defined or not.无论是否定义,它都会呈现文件路径

Try to do as follows.尝试执行以下操作。

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>
  )
}

const [filePaths, setFilePaths] = useState(); will initialize filePaths as undefined.将 filePaths 初始化为未定义。
so you can check firstly like if (!filePaths) return null in the parent;因此您可以首先检查if (!filePaths) return null在父项中if (!filePaths) return null or set initState in useState like @see https://reactjs.org/docs/hooks-reference.html#lazy-initial-state或在 useState 中设置 initState 像@see https://reactjs.org/docs/hooks-reference.html#lazy-initial-state

const [filePaths, setFilePaths] = useState(()=> {
    var fileContent = JSON.parse(fs.readFileSync("./config.json");
    var tempFilePaths = [];
    fileContent.FilePaths.forEach((file) => {
      tempFilePaths.push(file);
    });
    return tempFilePaths;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在父项更改时将道具传递给反应组件但不更新子项中的该道具? - How do I pass a prop to a react component yet not update that prop in the child when parent changes? 在 REACT.js 中,如何将状态从子组件传递到父组件作为道具 - In REACT.js how can I pass a state from child component up to Parent component as a prop 子组件中未定义的道具 - Undefined prop in child component 从父组件传递道具在子组件 React 中变为空 - Passing a prop from a Parent component becomes null in the Child component React 从父组件获取子组件 Prop - Getting Child Component Prop from the Parent Component 当我使用 React Hooks 将 boolean 从子组件传递到其父组件时出现了什么问题? - What is going wrong when I pass a boolean from a child to its parent component using React Hooks? 在 React 中将父组件(即“this”)作为 prop 完全传递给子组件是不是很糟糕? - Is it bad to pass a parent component (i.e. "this") completely to a child component as a prop in React? 如何从父组件 prop 访问子组件 prop - How to access the child component prop from parent component prop React Native:如何将参数从子组件道具传递给父组件 - React Native: How to pass params to parent component from child component prop 将本机传递函数作为prop反映到子组件 - React Native pass function to child component as prop
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM