reactjs - 组件未在状态更改时呈现
问题描述
我有一个包含反应表和按钮的组件。它应该从一个空表开始,用户单击按钮添加一行并输入数据。
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
不会改变原始数组而是返回一个新数组。
这是差异的示例:
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);
推荐阅读
- amazon-web-services - 在 AWS ECS 中发布微服务
- office-js - O365 Outlook 插件 - 撰写模式下的自动电子邮件解析
- spring - 如何配置 Spring Boot 以将 MultiPartFile 写入磁盘?
- json - 将嵌套数据从谷歌表发送到 API
- solr - 如何在不重新索引的情况下将唯一键更改为新字段并更新所有文档?
- java - 如何将新的 JVM 附加到生成的 Python 进程?
- c++ - 可以优化智能指针吗?
- android - SnappyDB 中的 byBatch(size) 是什么意思?
- node.js - 在 Windows 操作中心中未触发 notifier.on 点击事件
- flutter - Flutter:如何将 TweenAnimation 应用于 Transform 的多个属性?