我的目标是根据单击的列对 table 的数据进行排序。为了实现这个目标,我需要将关于 header
点击的信息从 child component
"Table"
传递给 parent component
“App”。
这是来自 child component
Table
:
const [keyclicked, setKeyclicked] = React.useState("");
const [sortOptions, setSortOptions] = React.useState({
first: "",
second: ""
});
const modalFunct = React.useMemo(() => {
if (document.getSelection(keyclicked.target).focusNode !== null) {
console.log(
document
.getSelection(keyclicked.target)
.focusNode.wholeText.toLowerCase()
);
let newsorting = sortOptions;
if (sortOptions.first !== "") {
newsorting.second = document
.getSelection(keyclicked.target)
.focusNode.wholeText.toLowerCase();
} else {
newsorting.first = document
.getSelection(keyclicked.target)
.focusNode.wholeText.toLowerCase();
}
setSortOptions(newsorting);
selectSorter(
document
.getSelection(keyclicked.target)
.focusNode.wholeText.toLowerCase()
);
}
}, [keyclicked]);
const renderHeader = () => {
let headerElement = ["id", "name", "email", "phone", "operation"];
return headerElement.map((key, index) => {
return (
<th onClick={setKeyclicked} key={index}>
{key.toUpperCase()}
</th>
);
});
};
const renderBody = () => {
console.log("renderBody-employees: ", employees);
return employees.map(({ id, name, email, phone }) => {
return (
<tr key={id}>
<td>{id}</td>
<td>{name}</td>
<td>{email}</td>
<td>{phone}</td>
<td className="operation">
<button className="button" onClick={() => removeData(id)}>
Delete
</button>
</td>
</tr>
);
});
};
return (
<>
<h1 id="title">Table</h1>
<h3>
{" "}
Lets go for a <FaBeer /> ?{" "}
</h3>
<table id="employee">
<thead>
<tr>{renderHeader()}</tr>
</thead>
<tbody>{renderBody()}</tbody>
</table>
</>
);
};
export default Table;
这是来自 App.js
:
import Table from "./Table";
const [selectedSortingOption, SetSelectedSortingOption] = React.useState(
null
);
return (
<div className="App">
<div align="center">
<button onClick={addSingleEmployee}>AddEmployee</button>
<Select
defaultValue={selectedSortingOption}
onChange={SetSelectedSortingOption}
options={sortingOptions}
/>
</div>
<div className="scrollable">
<Table
table_data={sortedData}
row_data={newEmployee}
basePageLink={""}
removeData={removeRaw}
selectSorter={selectHowToSort}
/>
</div>
<div align="center">
<button onClick={emptyTable}>EmptyTable</button>
</div>
</div>
); }
例如,当单击 email
标头时,我在控制台日志中得到以下输出:
`email` : which is correct
而这个 warning
- 错误信息:
Warning: Cannot update a component (`App`) while rendering a different component (`Table`). To locate the bad setState() call inside `Table`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
Table@https://oqx8ut.csb.app/src/Table/index.jsx:23:15
div
div
App@https://oqx8ut.csb.app/src/App.js:168:33
Table/index.jsx:23
指的是这一行:
React.useEffect(() => {
setEmployees(table_data);
return () => {
// clean-up function
};
}, [table_data]);
而 App.js:168
指的是这个:
const [selectedSortingOption, SetSelectedSortingOption] = React.useState(
null
);
我也尝试在 Child Component
"Table"
中这样做:
const [sortOptions, setSortOptions] = React.useState({
first: "",
second: ""
});
//const modalFunct = (key_clicked) => {
const modalFunct = React.useMemo(() => {
//console.log(keyclicked.target);
//console.log(document.getSelection(keyclicked.target).focusNode);
if (document.getSelection(keyclicked.target).focusNode !== null) {
console.log(
//selectSorter(
document
.getSelection(keyclicked.target)
.focusNode.wholeText.toLowerCase()
);
let newsorting = sortOptions;
if (sortOptions.first !== "") {
newsorting.second = document
.getSelection(keyclicked.target)
.focusNode.wholeText.toLowerCase();
} else {
newsorting.first = document
.getSelection(keyclicked.target)
.focusNode.wholeText.toLowerCase();
}
setSortOptions(newsorting);
//selectSorter(
//document
//.getSelection(keyclicked.target)
//.focusNode.wholeText.toLowerCase()
//);
}
}, [keyclicked]);
const memoizedSelectSorter = React.useMemo(() => {
selectSorter(sortOptions);
}, [sortOptions]);
但仍然得到同样的错误
我究竟做错了什么?如何将 email
信息(关于单击哪个标题的信息)从 Child component
"Table"
传递到要对数据进行排序的 Parent Component
"App"
?
回答1
你在你的代码中搜索这一行:return employees.map(({ id, name, email, phone }) => {
,你把 return 放在 Array.map() 之前会给你数组而不是 JSX 语法。尝试删除该行中的 return :
const renderBody = () => {
console.log("renderBody-employees: ", employees);
return employees.map(({ id, name, email, phone }) => { //<== remove this return here, put "?" in employees?.map to prevent crash app
return (
<tr key={id}>
<td>{id}</td>
....
可能 table_data
在您的 dependency
中使 Table
组件无限重新渲染导致 React 忙于渲染此组件,请尝试将其删除:
React.useEffect(() => {
setEmployees(table_data);
return () => {
// clean-up function
};
}, []); // <== Had remove table_data in dependency