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

时间:2020-06-07 11:40:22

标签: javascript reactjs closures react-hooks

哪种是在React功能组件中声明变量的最佳方法(从现在开始-RFC)?它与Similar question不能重复。

对于我来说,有几种声明变量的方法'

  1. 在RFC内使用import math distance_points=[] def euclidean_distance (points): return math.sqrt((x**2+y**2)) for (x,y) in (points): distance=euclidean_distance(points) distance_points.append(distance) print(distance_points) 进行声明-如果将其传递给const组件,则在每个渲染中,它将创建一个新引用,而HeavyComponent也将进行渲染。这不是一个好选择。
  2. 在RFC中用HeavyComponent声明-引用在后续渲染中将是相同的,这很好,但是,另一方面,我们使用的是useRef内部方法(函数调用-执行某些操作内幕工作)
  3. 在RFC(外部范围)之外用useRef声明-在这种情况下,引用将再次相同,因为它将从闭包中获取,我们不使用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} />); }); ,但是我不确定它是否比在RFC之外声明更好。

2 个答案:

答案 0 :(得分:3)

在功能组件中存储变量的最佳方法取决于您的useCase。

在大多数情况下,可以使用useRef钩子,因为它在函数的每个呈现器上都为您返回相同的变量实例。

不过,您也可以使用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提供一个记忆值

更新:

对于您的用例,有两种定义headerColumns的方法。

  • 组件外部的常量。将其声明为功能组件的常量外部变量在不希望更改值或不希望使用闭包中的任何值的情况下很有意义

  • 作为函数中的记忆值

 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赋值。

答案 1 :(得分:2)

在您的用例中,.pipe( map(<T>(item) => item.results[0].address_components), // another item in the pipeline map(values => values.filter(value => value.types.includes('locality')) ) 应该在外部范围内:

headerColumns

如果它是“只读”对象,则应在外部范围内。

请参见Why need useRef to contain mutable variable but not define variable outside the component function?

在当前情况下,如果您有N个const headerColumns = [ { children: "First Name", width: 240, flexGrow: 1, sortValue: (item) => item.FirstName, }, // more ]; export const UnemployedEmployeesReportPaper = React.memo((props) => {}); 组件,则将有N个UnemployedEmployeesReportPaper引用,相反,在外部范围内,所有组件将共享相同的不可变对象(不变,因为在您的用例中,它充当只读对象。