在 React 功能组件中声明静态变量的最佳方法是什么?



在React 功能组件中声明变量的最佳方式是什么(从现在开始 - RFC(? 它与类似的问题不重复。

至于我,有几种声明变量的方法">

  1. 在 RFC 中使用const声明它 - 如果我们将其传递给HeavyComponent组件,因此在每次渲染时,它将创建一个新的引用,HeavyComponent也会渲染。不是一个好的选择。
  2. 在 RFC 中使用useRef声明 - 引用在后续渲染中将是相同的,这很好,但另一方面,我们正在使用useRef内部方法(函数调用 - 它在后台完成一些工作(
  3. 使用
  4. RFC 之外的const声明(外部范围( - 在这种情况下,引用将再次相同,因为它将取自闭包,我们不使用useRef方法。但是,在这种特殊情况下,我们在外部作用域中声明该变量,它不会被垃圾回收,并且会导致内存泄漏(如果我们经常使用该情况(。

我知道,每种情况都有其优点和缺点。但是我们什么时候坚持某个选项呢?

已更新这是示例

export const UnemployedEmployeesReportPaper = React.memo((props: IProps) => {
const [filterText, setFilterText] = useState('');
const [tableData, setTableData] = useState([]);
const headerColumns = useRef([
{ children: 'First Name', width: 240, flexGrow: 1, sortValue: item => item.FirstName },
{ children: 'Last Name', width: 240, flexGrow: 1, sortValue: item => item.LastName },
{ children: 'Last day of employment', width: 240, flexGrow: 1, sortValue: item => moment(item.Since).format('L') },
]).current;
const filterEmployee = (event: SyntheticEvent): void => {
const { value } = event.target;
const { payload } = props.unemployedEmployees;
const newTableData = payload.filter((row: ISimpleEmployeeRowData): boolean =>
(row.FirstName).toLowerCase().includes(value.toLowerCase()));
setTableData(newTableData);
setFilterText(value);
};
const rows = useMemo(() => {
return tableData.map(entry => {
return {
data: [
{ children: entry.FirstName },
{ children: entry.LastName },
{ children: entry.Since },
],
onDoubleClick: (): void => props.goToEmployees(entry.ID),
// Empty onClick will turn the hovering of table on
onClick: () => {}
};
});
}, [tableData]);
useEffect(() => {
if (props.unemployedEmployees.payload) {
setTableData(props.unemployedEmployees.payload);
}
setFilterText('');
}, [props.unemployedEmployees]);

return (
<VTable
sortable
striped
rowHeight={36}
headerColumns={headerColumns}
rows={rows}
/>);
});

这里useRef使用,但我不确定它是否比在 RFC 之外声明它更好。

在功能组件中存储变量的最佳方式取决于您的用例。

在大多数情况下,您可以使用useRef hook,因为它在函数的每个渲染时都会返回相同的变量实例。

但是,您也可以定义一个变量并使用 useMemo 钩子分配其值。

喜欢

const val = useMemo(() => {
return some calculation based value or in general a normal value
},[]) // dependency array to recalculate value

您必须注意,useRef 可以帮助您解决闭包问题,并且在您想要使用受闭包影响的变量时会派上用场。例如,在 useEffect 中定义的具有空依赖项的 setInterval 函数中使用闭包中的值。

另一方面,useMemo 将帮助您防止变量的引用更改,而无需每次重新渲染。一个常见的用例是为 ContextProvider 提供一个记忆值

更新:

对于您的用例,有两种方法可以定义标头列。

  • 在组件外部作为常量。当值预计不会更改时,将其声明为功能组件外部的常量是有意义的,也不应使用闭包中的任何值

  • 作为函数中的记忆值

const headerColumns = useMemo( () => [
{ children: 'First Name', width: 240, flexGrow: 1, sortValue: item => item.FirstName },
{ children: 'Last Name', width: 240, flexGrow: 1, sortValue: item => item.LastName },
{ children: 'Last day of employment', width: 240, flexGrow: 1, sortValue: item => moment(item.Since).format('L') },
], []);

您必须注意,当您使用闭包中的值时,使用useMemo将值分配给headerColumns是有意义的。

在您的用例中,headerColumns应该在外部范围内:

const headerColumns = [
{
children: "First Name",
width: 240,
flexGrow: 1,
sortValue: (item) => item.FirstName,
},
// more
];
export const UnemployedEmployeesReportPaper = React.memo((props) => {});

如果它是"只读"对象,则应位于外部范围内。

请参阅为什么需要使用 Ref 来包含可变变量,但不定义组件函数外部的变量?。

在您当前的情况下,如果您有 N 个UnemployedEmployeesReportPaper组件,您将有 N 个headerColumns引用,而不是在外部作用域上,所有组件将共享同一个不可变对象(不可变,因为在您的用例中,它充当只读对象(。

相关内容

  • 没有找到相关文章

最新更新