You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React报错:对象不能作为React子元素,函数组件传参问题排查

问题:React Alert组件渲染报错及状态同步问题

报错信息

Uncaught Error: Objects are not valid as a React child (found: object with keys {message, showAlerts}). If you meant to render a collection of children, use an array instead.

父组件代码

import styled from "styled-components";
import { useTable } from "react-table";
import Alert from "react-bootstrap/Alert";
import Button from "react-bootstrap/Button";
import axios from "axios";

import AppAlerts from "./components/Alerts";

const Styles = styled.div`
  padding: 1rem;

  table {
    border-spacing: 0;
    border: 1px solid black;

    tr {
      :last-child {
        td {
          border-bottom: 0;
        }
      }
    }

    th,
    td {
      margin: 0;
      padding: 0.5rem;
      border-bottom: 1px solid black;
      border-right: 1px solid black;

      :last-child {
        border-right: 0;
      }
    }
  }
`;

function Table({ columns, data }) {
  // Use the state and functions returned from useTable to build your UI
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow
  } = useTable({
    columns,
    data
  });

  const [showAlert, setShowAlert] = useState(false);
  const [alertMessage, setAlertMessage] = useState("");
  const handleButttonClick = () => {
    setShowAlert(true);
    setAlertMessage("dummy text");
  };

  // Render the UI for table
  return (
    <div>
      <div>
        <AppAlerts message={alertMessage} showAlerts={showAlert} />;
      </div>

      <table {...getTableProps()}>
        <thead>
          {headerGroups.map((headerGroup) => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map((column) => (
                <th {...column.getHeaderProps()}>{column.render("Header")}</th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {rows.map((row, i) => {
            prepareRow(row);
            return (
              <tr {...row.getRowProps()}>
                {row.cells.map((cell) => {
                  return (
                    <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
      <Button onClick={handleButttonClick}>Open Alert box</Button>
    </div>
  );
}

function App() {
  // const [data, setData] = useState([]);
  // const [columns, setColumns] = useState([]);

  const columns = React.useMemo(
    () => [
      { Header: "Id", accessor: "id" },
      { Header: "Applicant", accessor: "applicant" },
      { Header: "Pincode", accessor: "pincode" },
      { Header: "District", accessor: "district" },
      { Header: "State", accessor: "state" }
    ],
    []
  );
  const data = React.useMemo(
    () => [
      {
        id: 18,
        applicant: "Buzz",
        pincode: 560096,
        district: 1,
        state: 1
      },
      {
        id: 19,
        applicant: "Sue",
        pincode: 560100,
        district: 2,
        state: 1
      }
    ],
    []
  );

  return (
    <div className="App">
      <Styles>
        <Table columns={columns} data={data} />
      </Styles>
    </div>
  );
}

export default App;

子组件代码

import { useEffect, useState } from "react";
import Alert from "react-bootstrap/Alert";

export default function AppAlerts(message, showAlerts) {
  const [show, setShow] = useState(showAlerts);

  return (
    <Alert
      variant="info"
      onClose={() => setShow(false)}
      show={show}
      dismissible
    >
      <p>{message}</p>
    </Alert>
  );
}

提问

请问我哪里出错了,应该如何修改?我尝试以常规方式渲染Alert子组件,希望点击按钮时Alert弹出,关闭弹窗时父组件的showAlerts状态也同步变为false。


解答

1. 渲染报错的原因及修复

React函数组件的props是单个对象参数,不是分开的独立参数。你的子组件AppAlerts写了function AppAlerts(message, showAlerts),这会导致第一个参数message实际上接收的是整个props对象(包含message和showAlerts两个键),第二个参数showAlerts是undefined。

当你在<p>{message}</p>里渲染这个对象时,React就会抛出“Objects are not valid as a React child”的错误。

修复方法:解构props对象,正确接收参数:

// 子组件修改为
export default function AppAlerts({ message, showAlerts, onClose }) {
  return (
    <Alert
      variant="info"
      onClose={onClose}
      show={showAlerts}
      dismissible
    >
      <p>{message}</p>
    </Alert>
  );
}

2. 状态同步问题的修复

你现在的子组件自己维护了show状态,关闭弹窗时只会修改子组件内部的状态,父组件的showAlert不会同步更新。要实现父子状态同步,应该把状态控制权交给父组件:

  • 父组件传递setShowAlert的回调给子组件
  • 子组件直接使用父组件的showAlerts控制显示,关闭时调用父组件的回调更新状态

父组件修改:在渲染AppAlerts时传递关闭回调:

// Table组件的return里修改AppAlerts的调用
<AppAlerts 
  message={alertMessage} 
  showAlerts={showAlert} 
  onClose={() => setShowAlert(false)} 
/>

子组件修改:移除内部的show状态,直接使用父组件传入的showAlerts和onClose:

import Alert from "react-bootstrap/Alert";

export default function AppAlerts({ message, showAlerts, onClose }) {
  return (
    <Alert
      variant="info"
      onClose={onClose}
      show={showAlerts}
      dismissible
    >
      <p>{message}</p>
    </Alert>
  );
}

另外,父组件的Table组件里还漏了导入useState,需要补上:

// 在Table组件顶部添加
import { useState } from "react";

内容的提问来源于stack exchange,提问作者viking

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 10:05:33