组件不在状态更改时呈现

Component not rendering on state change

我有一个包含 react-table 和按钮的组件。它应该以空 table 开头,用户单击按钮添加一行并输入数据。

import React from "react";
import {Button, Row} from "react-bootstrap";
import {useTable} from "react-table";

export default function PlantDetail() {
    const [plants, setPlants] = React.useState([])

    const data = React.useMemo(() => plants, [plants])
    const addRow = () => {
        plants.push({"species_id": "10002", "name": "Maria", "weight": 15})
        setPlants(plants)
    }
    const columns = React.useMemo(
        () => [
            {
                Header: "Name", accessor: "name",
            },
            {Header: "Weight", accessor: "weight"},
        ],
        []
    )

    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow,

    } = useTable({columns, data})


    return (<React.Fragment>
        <Row>
            <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 => {
                        prepareRow(row)
                        return (
                            <tr {...row.getRowProps()}>
                                {row.cells.map(cell => {
                                    return (
                                        <td {...cell.getCellProps()}>
                                            {cell.render('Cell')}
                                        </td>
                                    )
                                })}
                            </tr>
                        )
                    })}
                </tbody>
            </table>
        </Row>
        <Row>
            <Button onClick={addRow}>Button</Button>
        </Row>
    </React.Fragment>)
}

所以我只专注于创建一个新行,这就是为什么在这个例子中我只是添加一个硬编码值。

但是按钮不会导致渲染。添加了数据,但没有进行渲染。

我在这里错过了什么?

您正在使用 push 改变状态。

这会导致“错过”状态更新而不是重新渲染。当您的状态是对象或数组时,您需要在更新时传递一个新实例。

下面是 React 如何确定是否应该更新的简化示例:

const state = [1,2];

function setState(newState) {
  if (state !== newState) {
    console.log('re-render');
  } else {
    console.log('skip');
  }
}

// Wrong
state.push(3);
setState(state);

// Right
setState(state.concat(4));

有多种解决方案,但其中一种是 concat

setPlants(plants.concat({"species_id": "10002", "name": "Maria", "weight": 15}))

这会起作用,因为 concat 不会改变原始数组,而是 returns 一个新数组。

这是一个差异示例:

const arr1 = [1,2,3];
const arr2 = [1,2,3];

arr1.push(4);

console.log('arr1', arr1);

const arr3 = arr2.concat(4);

console.log('arr2', arr2);

console.log('arr3', arr3);