将对象值添加到 React 的 useMemo 挂钩
Adding object values to useMemo hook for React
我正在尝试使用从数据库中提取的数据创建一个 react-table 组件。从我阅读的文档 (https://react-table.tanstack.com/docs/quick-start) 来看,react-table 库似乎使用 useMemo 挂钩来创建将显示在 table 上的数据。但是,我在实际向 useMemo 挂钩添加数据时遇到了麻烦,因为我不熟悉它。
我有一个简单的 JS 对象,它保存我们数据库中发生的每一类中断的实例计数。获得计数后,我尝试将其传递给我的 useMemo 实例,但返回未定义 'streamCount' 的属性。我想我错误地将对象传递给了 useMemo。感谢任何帮助。
function Leaderboard(props){
const data = props.tableData;
console.log(data); //this is the data that is pulled from our DB and is passed as a prop into the component
let counts = {
streamCount: 0,
powerCount: 0,
internetCount: 0,
gamingPlatformCount: 0,
cableCount: 0,
websiteCount: 0,
} //the object that holds the number of instances each category occurs in our data
for(var i = 0; i < data.length; i++){ //checks the data and updates the counts for each category
switch(data[i].service_type) {
case "Streaming":
counts.streamCount += 1;
break;
case "Power":
counts.powerCount+= 1;
break;
case "Internet":
counts.internetCount+= 1;
break;
case "Gaming Platform":
counts.gamingPlatformCount += 1;
break;
case "Cable":
counts.cableCount += 1;
break;
case "Website":
counts.websiteCount += 1;
break;
default:
break;
}
}
console.log(counts) //This returns the correct values of each count when line 41-69 is commented, but returns 0 for all values when those lines are uncommented.
let outageCounts = React.useMemo(
(counts) => [
{
type: 'Streaming',
count: counts.streamCount,
},
{
type: 'Power',
count: counts.powerCount,
},
{
type: 'Internet',
count: counts.internetCount,
},
{
type: 'GamingPlatform',
count: counts.gamingPlatformCount,
},
{
type: 'Cable',
count: counts.cableCount,
},
{
type: 'Website',
count: counts.websiteCount,
},
],
[]
);
//this will be updated to have the accessor be 'count' from outageCounts instead of 'service_type' from data when the bug is resolved. For now it is just using data to test to see if the table would render at all.
const columns = React.useMemo(
() => [
{
Header: 'Service Type',
accessor: 'service_type',
},
],
[]
);
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable({ columns, data}) //data will eventually be changed to outageCounts
return (
<table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th
{...column.getHeaderProps()}
style={{
borderBottom: 'solid 3px red',
background: 'aliceblue',
color: 'black',
fontWeight: 'bold',
}}
>
{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()}
style={{
padding: '10px',
border: 'solid 1px gray',
background: 'papayawhip',
}}
>
{cell.render('Cell')}
</td>
)
})}
</tr>
)
})}
</tbody>
</table>
);
}
export default Leaderboard;
useMemo
钩子的回调函数不接受任何参数,它只接受一个回调函数,returns 一个你想要或需要记忆的值,以及一个依赖数组。
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Returns a memoized value.
Pass a “create” function and an array of dependencies. useMemo
will
only recompute the memoized value when one of the dependencies has
changed. This optimization helps to avoid expensive calculations on
every render.
将计算计数的逻辑移动到 useMemo
回调中,并使用 data
(道具值)作为依赖项。您可以 simplify/reduce 通过抽象将 service_type
映射到 counts
键之一然后映射回来但仅使用 service_type
作为 counts
键。通过此更改,您可以简单地使用动态对象属性来更新每种中断类型的计数。计算完计数后,从对象创建一个键值对数组,并将其映射到具有 type
和 count
键的对象数组。
const outageCounts = React.useMemo(() => {
const counts = {
Streaming: 0,
Power: 0,
Internet: 0,
"Gaming Platform": 0,
Cable: 0,
Website: 0
};
data.forEach(({ service_type }) => {
if (Object.hasOwnProperty.call(counts, service_type)) {
counts[service_type] += 1;
}
});
return Object.entries(counts).map(([type, count]) => ({ type, count }));
}, [data]);
function App({ data = [] }) {
const outageCounts = React.useMemo(() => {
const counts = {
Streaming: 0,
Power: 0,
Internet: 0,
"Gaming Platform": 0,
Cable: 0,
Website: 0
};
data.forEach(({ service_type }) => {
if (Object.hasOwnProperty.call(counts, service_type)) {
counts[service_type] += 1;
}
});
return Object.entries(counts).map(([type, count]) => ({ type, count }));
}, [data]);
//console.log({ outageCounts });
return (
<div className="App">
<h1>Outage Counts</h1>
<ul>
{outageCounts.map(({ type, count}) => (
<li key={type}>
{type}: {count}
</li>
))}
</ul>
</div>
);
}
const service_types = [
"Streaming",
"Power",
"Internet",
"Gaming Platform",
"Cable",
"Website"
];
// Generate "random" outage data
const data = Array.from({ length: Math.floor(Math.random() * 1000) }, () => ({
service_type: service_types[Math.floor(Math.random() * service_types.length)]
}));
const rootElement = document.getElementById("root");
ReactDOM.render(
<App data={data} />,
rootElement
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root" />
我正在尝试使用从数据库中提取的数据创建一个 react-table 组件。从我阅读的文档 (https://react-table.tanstack.com/docs/quick-start) 来看,react-table 库似乎使用 useMemo 挂钩来创建将显示在 table 上的数据。但是,我在实际向 useMemo 挂钩添加数据时遇到了麻烦,因为我不熟悉它。
我有一个简单的 JS 对象,它保存我们数据库中发生的每一类中断的实例计数。获得计数后,我尝试将其传递给我的 useMemo 实例,但返回未定义 'streamCount' 的属性。我想我错误地将对象传递给了 useMemo。感谢任何帮助。
function Leaderboard(props){
const data = props.tableData;
console.log(data); //this is the data that is pulled from our DB and is passed as a prop into the component
let counts = {
streamCount: 0,
powerCount: 0,
internetCount: 0,
gamingPlatformCount: 0,
cableCount: 0,
websiteCount: 0,
} //the object that holds the number of instances each category occurs in our data
for(var i = 0; i < data.length; i++){ //checks the data and updates the counts for each category
switch(data[i].service_type) {
case "Streaming":
counts.streamCount += 1;
break;
case "Power":
counts.powerCount+= 1;
break;
case "Internet":
counts.internetCount+= 1;
break;
case "Gaming Platform":
counts.gamingPlatformCount += 1;
break;
case "Cable":
counts.cableCount += 1;
break;
case "Website":
counts.websiteCount += 1;
break;
default:
break;
}
}
console.log(counts) //This returns the correct values of each count when line 41-69 is commented, but returns 0 for all values when those lines are uncommented.
let outageCounts = React.useMemo(
(counts) => [
{
type: 'Streaming',
count: counts.streamCount,
},
{
type: 'Power',
count: counts.powerCount,
},
{
type: 'Internet',
count: counts.internetCount,
},
{
type: 'GamingPlatform',
count: counts.gamingPlatformCount,
},
{
type: 'Cable',
count: counts.cableCount,
},
{
type: 'Website',
count: counts.websiteCount,
},
],
[]
);
//this will be updated to have the accessor be 'count' from outageCounts instead of 'service_type' from data when the bug is resolved. For now it is just using data to test to see if the table would render at all.
const columns = React.useMemo(
() => [
{
Header: 'Service Type',
accessor: 'service_type',
},
],
[]
);
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable({ columns, data}) //data will eventually be changed to outageCounts
return (
<table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th
{...column.getHeaderProps()}
style={{
borderBottom: 'solid 3px red',
background: 'aliceblue',
color: 'black',
fontWeight: 'bold',
}}
>
{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()}
style={{
padding: '10px',
border: 'solid 1px gray',
background: 'papayawhip',
}}
>
{cell.render('Cell')}
</td>
)
})}
</tr>
)
})}
</tbody>
</table>
);
}
export default Leaderboard;
useMemo
钩子的回调函数不接受任何参数,它只接受一个回调函数,returns 一个你想要或需要记忆的值,以及一个依赖数组。
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Returns a memoized value.
Pass a “create” function and an array of dependencies.
useMemo
will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render.
将计算计数的逻辑移动到 useMemo
回调中,并使用 data
(道具值)作为依赖项。您可以 simplify/reduce 通过抽象将 service_type
映射到 counts
键之一然后映射回来但仅使用 service_type
作为 counts
键。通过此更改,您可以简单地使用动态对象属性来更新每种中断类型的计数。计算完计数后,从对象创建一个键值对数组,并将其映射到具有 type
和 count
键的对象数组。
const outageCounts = React.useMemo(() => {
const counts = {
Streaming: 0,
Power: 0,
Internet: 0,
"Gaming Platform": 0,
Cable: 0,
Website: 0
};
data.forEach(({ service_type }) => {
if (Object.hasOwnProperty.call(counts, service_type)) {
counts[service_type] += 1;
}
});
return Object.entries(counts).map(([type, count]) => ({ type, count }));
}, [data]);
function App({ data = [] }) {
const outageCounts = React.useMemo(() => {
const counts = {
Streaming: 0,
Power: 0,
Internet: 0,
"Gaming Platform": 0,
Cable: 0,
Website: 0
};
data.forEach(({ service_type }) => {
if (Object.hasOwnProperty.call(counts, service_type)) {
counts[service_type] += 1;
}
});
return Object.entries(counts).map(([type, count]) => ({ type, count }));
}, [data]);
//console.log({ outageCounts });
return (
<div className="App">
<h1>Outage Counts</h1>
<ul>
{outageCounts.map(({ type, count}) => (
<li key={type}>
{type}: {count}
</li>
))}
</ul>
</div>
);
}
const service_types = [
"Streaming",
"Power",
"Internet",
"Gaming Platform",
"Cable",
"Website"
];
// Generate "random" outage data
const data = Array.from({ length: Math.floor(Math.random() * 1000) }, () => ({
service_type: service_types[Math.floor(Math.random() * service_types.length)]
}));
const rootElement = document.getElementById("root");
ReactDOM.render(
<App data={data} />,
rootElement
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root" />