【问题标题】:How to fix Error: object is not valid as React child如何修复错误:对象作为 React 子对象无效
【发布时间】:2021-09-08 17:51:08
【问题描述】:

我正在学习 React,我正在尝试开发一个代码来从 api“数字 API”中获取具有相应有趣事实的随机 10 个数字。

我面临的问题是,当我运行代码时,出现错误

“错误:对象作为 React 子级无效(找到:[object Promise])。如果您要渲染子级集合,请改用数组”

下面我附上了代码:

const originalArray = new Array(10).fill(0);
const mappedArray = originalArray.map((n, index) =>
  Math.floor(Math.random() * 100)
);

console.log("mappedArray", mappedArray);
console.log("joined array string", mappedArray.join(","));

async function callApi(numbers) {
  const fetchResponse = await fetch(`http://numbersapi.com/${numbers}/math`);

  if (fetchResponse.ok) {
    const data = await fetchResponse.json();
    console.log("all good, heres the response", data);
  } else console.log("There was a problem");
}


const Number = async() => {
    const [add, setAdd] = React.useState([]); // <-- valid initial empty state

    React.useEffect(() => {
        callApi(mappedArray).
          then(values => setAdd(values));
      }, []); // <-- invoke on component mount
    
  <div className="container">
    {add.map((newlist, i) => (
      <div className="item" key={i}>
        {newlist}
      </div>
    ))}
  </div>
);

export default Number;

有人可以帮我解决这个问题吗?谢谢

【问题讨论】:

  • newlist 是一个对象吗?如果是这样,您不能将其作为子对象传递,如果您想查看整个对象或渲染单个属性,则需要对其进行字符串化。

标签: javascript reactjs


【解决方案1】:
  1. You need to maintain state。 React 的生命周期非常特别。所以这里我有一个data 状态,以及一个更新它的函数 - setData

  2. 对于 React 函数组件,我们使用 useEffect - 本质上是类组件中的旧 componentDidMount - 在组件首次挂载时加载数据。然后我们可以使用我们现在知道的对象数组来设置状态。

  3. 一旦状态更新,组件就会重新渲染。然后,您可以使用作为键的键和作为文本源的值来迭代 Object.entries

function Number() {

  // Initialise the state with an empty array
  const [data, setData] = useState([]);

  // Separate out the function that creates the number array
  function createNumbers() {
    const originalArray = new Array(10).fill(0);
    return originalArray.map(() => Math.floor(Math.random() * 100)).join('');
  }

  useEffect(() => {
    async function getNumbers() {
      try {
        const res = await fetch(`http://numbersapi.com/${createNumbers()}/math`);
        const data = await res.json();

        // Set the new component state using the data
        setData(data);
      } catch (err) {
        console.log(err);
      }
    }
    getNumbers();
  }, []);

  return (
    <div className="container">
      {Object.entries(data).map(([key, value]) => (
        <div className="item" key={key}>
          {value}
         </div>
       ))}
     </div>
   );

};

 export default Number;

【讨论】:

  • 执行上述代码时出现“Unexpected token i in JSON”错误
【解决方案2】:

那是因为您的 add 函数仍然返回 Promise,因为它是 async 函数

您仍然需要await 以完成add,然后使用它:

类似这样的:

const Number = async () => {
  const data = await add;
    <div className="container">
      {data.map((newlist, i) => (
        <div className="item" key={i}>
          {newlist}
        </div>
      ))}
    </div>;
};

【讨论】:

  • 我尝试了您上面提到的更改,但不幸的是发生了同样的错误
【解决方案3】:

callApiasync 所以它隐式返回一个 Promise,你将它保存到 add 并尝试渲染。这就是 React 抱怨的对象。

您将希望在 React 组件生命周期内调用此函数并将结果保存到要呈现的状态中。

const Number = () => {
  const [add, setAdd] = React.useState([]); // <-- valid initial empty state

  React.useEffect(() => {
    callApi(mappedArray).
      then(values => setAdd(values));
  }, []); // <-- invoke on component mount

  return (
    <div className="container">
      {add.map((newlist, i) => (
        <div className="item" key={i}>
          {newlist}
        </div>
      ))}
    </div>
  );
};

当您将逗号分隔的数字列表发送到此 numbersapi 时,它会返回一个不可呈现为数组的 JSON 对象。

响应格式始终是从数字到事实的 JSON 映射, 最多 100 个数字。

回复http://numbersapi.com/53,65,70/math的示例

{
  "53": "53 is the 16thprime number.",
  "65": "65 is the 23rdsemiprime and the 3rd of the form (5.q)it is an octagonal number.",
  "70": "70 is the smallest weird number."
}

您似乎想将值保存到状态中:

React.useEffect(() => {
  callApi(mappedArray).
    then(result => setAdd(Object.values(result)));
}, []);

或者你可以在渲染时获取值的数组:

return (
  <div className="container">
    {Object.values(add).map((newlist, i) => (
      <div className="item" key={i}>
        {newlist}
      </div>
    ))}
  </div>
);

如果您需要键和值,则使用Object.entries 获取键值对数组。

例子:

[
  ['53', '53 is the 16thprime number.'],
  ['65', '65 is the 23rdsemiprime and the 3rd of the form (5.q)it is an octagonal number.'],
  ['70', '70 is the smallest weird number.'],
]
return (
  <div className="container">
    {Object.entries(add).map(([key, value], i) => (
      <div className="item" key={key}>
        {key}: {value}
      </div>
    ))}
  </div>
);

【讨论】:

  • 我对代码进行了更改,但仍然出现错误“错误:对象作为 React 子项无效(找到:[object Promise])。如果您打算渲染一组子项,改用数组”...我还更新了问题中的代码
  • @Joskaa add 的结构是什么?是数字数组还是对象数组?
  • @Drew Reese 添加包含对象数组
  • 我理解了 object.entries 函数。但这是一个新错误“TypeError:无法将未定义或 null 转换为对象”。我认为参数 {values} 是 void
  • @Joskaa 我之前没有发现这个问题,但是你的callApi 函数需要返回解析后的data JSON 值,否则是的,这是一个无效的返回。
猜你喜欢
  • 1970-01-01
  • 2019-07-10
  • 1970-01-01
  • 2016-10-26
  • 2021-06-22
  • 2021-12-15
  • 2021-08-05
  • 2018-11-12
  • 2021-06-07
相关资源
最近更新 更多