Which is the best way to declare variables in React functional components (From now on - RFC)? It is not duplicate to Similar question this one.
As for me, there are a few ways of declaring variables `
- Declaring it with
const
inside RFC - If we pass this to theHeavyComponent
component, so on each render, it will create a new reference, andHeavyComponent
will render too. Not a good option. - Declaring with
useRef
inside RFC - The reference will be the same within subsequent renders, which is good, but on the other hand, we are usinguseRef
internal method (Function call - which does some job under the hood) - Declaring with
const
outside of RFC (outer scope) - In this case, the reference will be again the same, as it will be taken from the closure and we don't useuseRef
method. But, in this particular case, we declare that variable in the outer scope and it is not being garbage collected and will cause memory leaks (if we use that cases very often).
I know, each case has its pros and cons. But when do we stick with a certain option?
UPDATED Here is the example
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}
/>);
});
Here is used useRef
, but I am not sure if it's better than just declaring it outside of RFC.