javascript - 复选框 onchanged 未在反应中更新
问题描述
这是我第一次开发 React 应用程序。
我在react中检索checkedMap useState钩子时遇到问题,只要复选框被选中然后未选中,它就不会更新其状态。状态似乎保存了检查的条目,无论下一个实例是否已经取消选中。
我通过以下方式访问了值:Array.from(checkedMap.keys()));
场景 1 复选框 A - 勾选 复选框 B - 勾选
checkedMap= 复选框 A 和 B 的 id
场景 2 复选框 A - 勾选 复选框 B - 未勾选
checkedMap= 仍然是 Checkbox A 和 B 的 id //应该是 Checkbox A 的 id
非常感谢您的帮助。
import React, { useState, useEffect, useRef } from "react";
// Simulate a server
const getServerData = async ({ filters, sortBy, pageSize, pageIndex }) => {
await new Promise(resolve => setTimeout(resolve, 500));
// Ideally, you would pass this info to the server, but we'll do it here for convenience
const filtersArr = Object.entries(filters);
// Get our base data
const res = await axios.get(
`url here`
);
let rows = res.data;
// Apply Filters
if (filtersArr.length) {
rows = rows.filter(row =>
filtersArr.every(([key, value]) => row[key].includes(value))
);
}
// Apply Sorting
if (sortBy.length) {
const [{ id, desc }] = sortBy;
rows = [...rows].sort(
(a, b) => (a[id] > b[id] ? 1 : a[id] === b[id] ? 0 : -1) * (desc ? -1 : 1)
);
}
// Get page counts
const pageCount = Math.ceil(rows.length / pageSize);
const rowStart = pageSize * pageIndex;
const rowEnd = rowStart + pageSize;
// Get the current page
rows = rows.slice(rowStart, rowEnd);
return {
rows,
pageCount
};
};
export default function({ infinite }) {
const [checkedMap, setCheckedMap] = useState(new Map());
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const currentRequestRef = useRef();
let newMap = new Map();
const fetchData = async () => {
setLoading(true);
// We can use a ref to disregard any outdated requests
const id = Date.now();
currentRequestRef.current = id;
// Call our server for the data
const { rows, pageCount } = await getServerData({
filters,
sortBy,
pageSize,
pageIndex
});
// If this is an outdated request, disregard the results
if (currentRequestRef.current !== id) {
return;
}
// Set the data and pageCount
setData(rows);
setState(old => ({
...old,
pageCount
}));
rows.forEach(row => newMap.set(row, false));
//setCheckedMap(newMap);
setLoading(false);
};
const handleCheckedChange = transaction_seq => {
let modifiedMap = checkedMap;
modifiedMap.set(transaction_seq, !checkedMap.get(transaction_seq));
setCheckedMap(modifiedMap);
};
const columns = [
{
Header: "Transaction(s)",
className: "left",
columns: [
{
id: "checkbox",
accessor: "checkbox",
Cell: ({ row }) => {
return (
<input
type="checkbox"
className="checkbox"
checked={checkedMap.get(row.original.transaction_seq)}
onChange={() =>
handleCheckedChange(row.original.transaction_seq)
}
/>
);
},
const state = useTableState({ pageCount: 0 });
const [{ sortBy, filters, pageIndex, pageSize }, setState] = state;
const paginationButtons = (
<React.Fragment>
<Button onClick={() => reprocessConfirmation()}>Reprocess</Button>
<Button onClick={() => reprocessConfirmation()}>View Details</Button>
</React.Fragment>
);
function reprocessConfirmation() {
let confirmation = window.confirm(
"Do you want to reprocess transaction sequence " +
Array.from(checkedMap.keys())
);
if (confirmation === true) console.log(Array.from(checkedMap.keys()));
else console.log("CANCEL");
}
function updateConfirmation() {
let confirmation = window.confirm("Do you want to update transaction");
if (confirmation === true) console.log("OK");
else console.log("CANCEL");
}
// When sorting, filters, pageSize, or pageIndex change, fetch new data
useEffect(() => {
fetchData();
}, [sortBy, filters, pageIndex, pageSize]);
return (
<React.Fragment>
<MyTable
{...{
data,
checkedMap,
paginationButtons,
columns,
infinite,
state, // Pass the state to the table
loading,
manualSorting: true, // Manual sorting
manualFilters: true, // Manual filters
manualPagination: true, // Manual pagination
disableMultiSort: true, // Disable multi-sort
disableGrouping: true, // Disable grouping
debug: true
}}
/>
</React.Fragment>
);
}
解决方案
由于您只是在选中和取消选中切换值,因此当未选中复选框时,键仍然存在,您必须删除键或在地图中查找真实值,而不仅仅是检查键是否存在.
第二个解决方案的代码片段
function reprocessConfirmation() {
const keys = [];
checkedMap.forEach((value, key) => {
if(value) keys.push[key]
})
let confirmation = window.confirm(
"Do you want to reprocess transaction sequence " +
keys
);
if (confirmation === true) console.log(keys);
else console.log("CANCEL");
}
推荐阅读
- ruby-on-rails - 有没有人建议我如何或在哪里获得作为初学者程序员的一对一指导(最好是免费的)?
- php - Composer 安装错误 - jms-security-extra-bundle
- firebase - 如何在 https 而不是 http 上运行 firebase(函数)模拟器?
- sql - 如何pring节点sequelize查询但不执行
- sorting - Kotlin 链表:如何检查给定列表是否已排序(降序)
- java - 我如何只运行单元测试而不是使用 maven 在构建阶段运行集成测试
- r - 无法将反应值传递给闪亮的变量
- c++ - 如何检查一个类型是否是 std::bitset 的特化?
- spring-webflux - 如何将 Prometheus 与 ReactiveFeignClient 集成以测量从客户端调用返回的每个状态代码的响应时间/点击次数
- typescript - angular8中的可观察和订阅和承诺有什么区别