![](/img/trans.png)
[英]best way to abstract forms and inputs using React functional components?
[英]What is the best way to declare static variables in React functional components?
在 React 功能組件中聲明變量的最佳方式是什么(從現在開始 - RFC)? 這與類似的問題不重復。
至於我,有幾種聲明變量的方法`
const
聲明它 - 如果我們將它傳遞給HeavyComponent
組件,那么在每次渲染時,它都會創建一個新的引用, HeavyComponent
也會渲染。 不是一個好的選擇。useRef
聲明 - 在隨后的渲染中引用將是相同的,這很好,但另一方面,我們正在使用useRef
內部方法(函數調用 - 它在后台做了一些工作)const
聲明 - 在這種情況下,引用將再次相同,因為它將取自閉包並且我們不使用useRef
方法。 但是,在這種特殊情況下,我們在外部 scope 中聲明該變量並且它沒有被垃圾收集,並且會導致 memory 泄漏(如果我們經常使用這種情況)。我知道,每種情況都有其優點和缺點。 但是我們什么時候堅持使用某個選項呢?
更新這里是例子
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 鈎子,因為它在 function 的每次渲染上都會返回相同的變量實例。
但是,您也可以使用 useMemo 掛鈎定義變量並為其賦值。
喜歡
const val = useMemo(() => {
return some calculation based value or in general a normal value
},[]) // dependency array to recalculate value
您必須注意 useRef 可以幫助您解決閉包問題,並且當您想要使用受閉包影響的變量時會派上用場。 例如,在 useEffect 中定義的 setInterval function 中使用閉包中的值,並且具有空依賴項。
另一方面,useMemo 將幫助您防止每次重新渲染的變量的引用更改。 一個常見的用例是為 ContextProvider 提供一個記憶值
更新:
對於您的用例,有兩種方法可以定義 headerColumns。
在組件之外作為常數。 當值預計不會改變時,將其聲明為函數組件外部的常量是有意義的,也不需要使用閉包中的任何值
作為 function 中的記憶值
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
應該在外部 scope 中:
const headerColumns = [
{
children: "First Name",
width: 240,
flexGrow: 1,
sortValue: (item) => item.FirstName,
},
// more
];
export const UnemployedEmployeesReportPaper = React.memo((props) => {});
如果它是“只讀”object,它應該在外部 scope 中。
請參閱為什么需要 useRef 包含可變變量但不在組件 function 之外定義變量? .
在您當前的情況下,如果您有 N 個UnemployedEmployeesReportPaper
組件,您將有 N 個headerColumns
引用,而不是在外部 scope 上,所有組件將共享相同的不可變 object (不可變,因為在您的用例中,它充當只讀對象)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.