簡體   English   中英

在 React 功能組件中聲明 static 變量的最佳方法是什么?

[英]What is the best way to declare static variables in React functional components?

在 React 功能組件中聲明變量的最佳方式是什么(從現在開始 - RFC)? 這與類似的問題不重復。

至於我,有幾種聲明變量的方法`

  1. 在 RFC 中用const聲明它 - 如果我們將它傳遞給HeavyComponent組件,那么在每次渲染時,它都會創建一個新的引用, HeavyComponent也會渲染。 不是一個好的選擇。
  2. 在 RFC 中使用useRef聲明 - 在隨后的渲染中引用將是相同的,這很好,但另一方面,我們正在使用useRef內部方法(函數調用 - 它在后台做了一些工作)
  3. 在 RFC(外部范圍)之外使用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') },
    ], []);

當您使用閉包中的值時,您必須注意使用useMemoheaderColumns賦值是有意義的。

在您的用例中, 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM