I'm trying to render an Alert component, when a prop is passed to it from the parent component it should render, but I'm getting an error
Uncaught Error: Object is not a valid React child element (Found: Object with keys {message, showAlerts}. If you want to render a collection of child elements, use an array instead.
I'm not sure why React treats my function component as an object. Code sandbox link: https://codesandbox.io/s/exciting-smoke-mij6ke?file=/src/App.js:0-3054
This is the parent component:
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;
Subassembly:
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> ); }
What am I doing wrong here and what should I change?
I try to render Alerts' child components in a way that I think is accepted. When the button is clicked, the Alert component must render and open the alert box. When closing an alert, the state variable in the parent component that displays the alerts (showAlerts) must also be changed to 'false'.
P粉4929595992023-09-11 10:02:44
Translate the following sentence into Chinese, retain the html code, and do not need to add new content:
export default function AppAlerts(message, showAlerts) { ... }
become:
export default function AppAlerts({message, showAlerts}) { ... }
Because props are always an object, and they are passed as the first parameter.
Using curly braces in the parameter list means that you are destructuring the first parameter (i.e. the props parameter).