错误:对象作为 React 子对象无效(找到:带有键 low, high 的对象)

Posted

技术标签:

【中文标题】错误:对象作为 React 子对象无效(找到:带有键 low, high 的对象)【英文标题】:Error: Objects are not valid as a React child (found: object with keys low, high)错误:对象作为 React 子对象无效(找到:带有键 low, high 的对象) 【发布时间】:2021-06-20 13:55:54 【问题描述】:

我对编码很陌生,这是我在 Stack Overflow 上的第一篇文章。我正在尝试构建一个 React 应用程序。这是回购: https://github.com/Amaro-Koberle/k-net/

这是项目的托管版本(非常早期的阶段): https://quizzical-edison-523c55.netlify.app/

有两个组件会导致问题:NodeDisplay.jsEditNode.js。 这两个组件都呈现所有传入和传出链接的列表(该应用程序是图形可视化,当您单击节点时,侧边栏应该显示节点的内容以及连接到它的所有链接的列表)。我知道问题出在这个列表上,因为当我将相应的部分注释掉时,事情又开始起作用了。 每当 React 尝试渲染这些列表中的任何一个时,应用程序都会崩溃并且我会收到以下错误: Error: Objects are not valid as a React child (found: object with keys low, high). If you meant to render a collection of children, use an array instead.

NodeDisplay.js(导致问题的部分当前已被注释掉,因此您可以单击托管应用程序中的节点而不会崩溃)

import  MdEdit  from "react-icons/md";
import  uuid  from "uuidv4";

export default function NodeDisplay( currNode, setEditing ) 
  if (currNode.id === "") 
    console.log("No node is currently selected");
    return null;
  

  return (
    <div className="mt-4">
      <div className="flex items-center space-x-2 text-lg">
        <h3>currNode.title</h3>
        <button className="edit-button" onClick=() => setEditing(true)>
          <MdEdit></MdEdit>
        </button>
      </div>
      <div className="mt-4">
        <p className="text-sm">currNode.description</p>
        <div>
          <div className="mt-4">
            <h5>Incoming Links</h5>
            /* <ul>
              currNode.inLinks.map((link) => (
                <li key=uuid>link</li>
              ))
            </ul>
          </div>
          <div className="mt-4">
            <h5>Outgoing Links</h5>
            <ul>
              currNode.outLinks.map((link) => (
                <li key=uuid>link</li>
              ))
            </ul> */
          </div>
        </div>
      </div>
    </div>
  );

EditNode.js(此处列表未注释掉,因此当您尝试编辑节点(通过单击小铅笔图标)时应用仍然会崩溃

import React from "react";
import  useState  from "react";
import  MdClose  from "react-icons/md";
import  uuid  from "uuidv4";

export default function EditNode(
  currNode,
  setCurrNode,
  setEditing,
  updateGraph,
  createLink,
  removeLink,
) 
  const [sourceInput, setSourceInput] = useState("");
  const [targetInput, setTargetInput] = useState("");

  return (
    <div className="mt-4">
      <div className="flex items-center space-x-2 text-lg">
        <>
          <h3>Edit Node</h3>
        </>
        <>
          <button onClick=() => setEditing(false)>
            <MdClose></MdClose>
          </button>
        </>
      </div>
      <form className="mt-4">
        /* title and description */
        <>
          <label className="label" htmlFor="title">
            Title
          </label>
          <>
            <input
              className="w-full input"
              type="text"
              id="title"
              placeholder="Title"
              value=currNode.title
              onInput=(e) =>
                setCurrNode( ...currNode, title: e.target.value )
              
            ></input>
          </>
          <>
            <label className="label" htmlFor="description">
              Description
            </label>
            <>
              <textarea
                className="w-full input"
                rows="5"
                id="description"
                placeholder="Description"
                value=currNode.description
                onInput=(e) =>
                  setCurrNode( ...currNode, description: e.target.value )
                
              ></textarea>
            </>
          </>
        </>
        /* links */
        <>
          /* incoming links */
          <div className="mt-4">
            <h4>Incoming Links</h4>
            <>
              <label className="label" htmlFor="createInLink">
                Source
              </label>
              <div className="inline-flex space-x-1">
                <input
                  className="input"
                  type="text"
                  id="createInLink"
                  placeholder="Source node ID"
                  value=sourceInput
                  onInput=(e) => setSourceInput(e.target.value)
                ></input>
                <>
                  <button
                    className="btn"
                    type="button"
                    onClick=() => createLink(sourceInput, currNode.id)
                  >
                    Connect
                  </button>
                </>
              </div>
            </>
            <ul>
              currNode.inLinks.map((link) => 
                return (
                  <li key=uuid()>
                    <span>link</span>
                    <button
                      className="btn"
                      type="button"
                      onClick=() => removeLink(link, currNode.id)
                    >
                      Remove
                    </button>
                  </li>
                );
              )
            </ul>
          </div>
          /* outgoing links */
          <div className="mt-4">
            <h4>Outgoing Links</h4>
            <>
              <label className="label" htmlFor="createOutLink">
                Target
              </label>
              <div className="inline-flex space-x-1">
                <>
                  <input
                    className="input"
                    type="text"
                    id="createOutLink"
                    placeholder="Target node ID"
                    value=targetInput
                    onInput=(e) => setTargetInput(e.target.value)
                  ></input>
                </>
                <>
                  <button
                    className="btn"
                    type="button"
                    onClick=() => createLink(currNode.id, targetInput)
                  >
                    Connect
                  </button>
                </>
              </div>
            </>
            <ul>
              currNode.outLinks.map((link) => 
                return (
                  <li key=uuid()>
                    <span>link</span>
                    <button
                      className="btn"
                      type="button"
                      onClick=() => removeLink(currNode.id, link)
                    >
                      Remove
                    </button>
                  </li>
                );
              )
            </ul>
          </div>
          /* <button className="btn" type="button" onClick=updateGraph>
            Save
          </button> */
        </>
      </form>
    </div>
  );

关于此错误还有其他 Stack Overflow 问题,但阅读答案并没有帮助,因为我仍然不明白这个问题,我不明白需要进行哪些更改来修复它。关于我的具体情况,我希望我不会再次询问,以免造成麻烦。

任何帮助将不胜感激。

【问题讨论】:

我必须浏览您的 Github 存储库(您的项目看起来相当复杂!)才能准确找到 link 在这些列表中的内容(即 currNode.inLinks 的成员 - 但它似乎很明显它是一个“普通对象”,因此您不能直接将其渲染为link。我不知道您应该做什么,因为这取决于这些对象的内容以及您实际想要渲染的方式那个内容。 感谢您的快速回复!哈哈,是的,我想我的第一个编程项目比我能咀嚼的要多一点。所以,currNode 是当前选中的节点。所有节点都是对象,具有id(字符串)、title(字符串)等的键。其中一个键是 inLinks,它是一个数组,其中每个元素都是另一个节点的 id(字符串)。假设 currNode 有id: "1"。如果有另一个节点(例如,id: "2")具有从它到节点 1 的链接,则将具有连接节点("2")的 id 的元素添加到节点 1 的 inLinks 数组中。跨度> 对象中有另一个数组,其键为 outLinks,其工作方式与 inLinks 完全相同,但它跟踪传出连接而不是传入连接(此图中的链接是定向的,所以有区别)。我只是想列出通向所选节点currNode 的链接。现在,每个链接只是一个带有两个键 source: "", target: "" 的对象,其中记录了源节点和目标节点的 id。无论如何,通过第二个节点(第一个节点是选定的currNode)引用它们来列出链接是一种临时解决方案。 最终我希望链接能够像节点一样携带内容(标题、描述等),但现在他们没有任何内容。最终,我希望currNode 的连接链接的列表项是交互式的(以便您可以单击它们以导航到链接,或者您可以展开列表项以查看更多详细信息......类似的东西),但我认为仅列出 id 将是一个不错的第一步。我希望详细说明会使事情更清楚。我仍然不确定如何避免此错误,同时仍然列出通向和来自所选节点的链接。 感谢您的回复 - 抱歉耽搁了。我不确定我还能说什么 - 我无法“看到”你的数据中的内容(如果你不知道,你可以 console.log 它),我也不知道问题是否来自inLinksoutLinks。而且我对错误消息提到错误对象具有键highlow 的事实感到困惑,这与您的任何描述都不匹配。但是无论如何,如果您的link 是具有sourcetarget 属性的对象,您可以执行例如&lt;span&gt;link.source&lt;/span&gt;target 相同),但不仅仅是link。希望这会有所帮助。 【参考方案1】:

在我的例子中,将 &lt;span&gt;link&lt;/span&gt; 更改为 &lt;span&gt;link.low&lt;/span&gt; 消除了错误,因为这些点直接对孩子做出反应。

令人困惑的是link 不应该有任何名为lowhigh 的属性。软管来自neo4j的javascript驱动程序h的一些问题,它不能很好地处理整数。在后端,不得不改变

const nodes = nodesResult.records.map((r) => 
    return 
      id: r.get("id").toNumber(),
      inLinks: r.get("inLinks"),
      outLinks: r.get("outLinks"),
      title: r.get("title"),
      description: r.get("description"),
    ;
  );

const nodes = nodesResult.records.map((r) => 
    return 
      id: r.get("id").toNumber(),
      inLinks: r.get("inLinks").map((inLink) => inLink.toNumber()),
      outLinks: r.get("outLinks").map((outLink) => outLink.toNumber()),
      title: r.get("title"),
      description: r.get("description"),
    ;
  );

注意我添加了.map((inLink) =&gt; inLink.toNumber()).map((outLink) =&gt; outLink.toNumber())

这解决了问题,到达前端的数据现在是我所期望的(即inLinks 的数组和outside Links 的数组,而不是带有h 键high: 的对象和low:

如果其他人遇到此问题,我希望这会有所帮助。

【讨论】:

以上是关于错误:对象作为 React 子对象无效(找到:带有键 low, high 的对象)的主要内容,如果未能解决你的问题,请参考以下文章

对象作为 React 子对象无效(找到:带有键 job 的对象)。如果您打算渲染一组孩子,请改用数组

错误:对象作为 React 子项无效(找到:带有键 的对象)。改用数组

错误:对象作为 React 子对象无效(找到:带键的对象..........)

错误:对象作为 React 子项无效(找到:带有键 的对象)。如果您打算渲染一组孩子,请改用数组

对象作为 React 子对象无效。如果您打算渲染一组子项,请改用数组 - 错误 Solidity - React

对象无效,因为React子反应错误?