@MaksZhukov
programer

Почему заходит в render функцию через react-hooks?

Всем привет, это отрывок кастомного хука, не подскажите почему в renderSourceList он не заходит(как и нужно, если sources не изменились), а в renderItem заходит всегда(хотя я и здесь использую useMemo)?
const renderItem = useMemo(() => (source) => {
        const { name: sourceName } = source;
        const labelClassName = `source__label-name source__label-name-${sourceName.toLowerCase()}`;
        return (
            <List.Item className="source">
                <Checkbox
                    disabled={source.name === 'radius'}
                    checked={source.isSelected}
                    onChange={() => handleSourceChecked(source)}
                    className="source__checkbox"
                />
                <span className={classNames('source__label', labelClassName)}>
                    {dataSourceLabelConfig[sourceName] || sourceName.toUpperCase() }
                </span>
                <span className="source__label">{`${source.nodeCount} nodes`}</span>
                <span className="source__label source__label-date">
                    {fromNow(source.updated)}
                </span>
                <button className="source__button" type="button" onClick={() => handleSourceRefresh(source)}>
                    <Icon className="source__icon" type="reload" width="20" height="20" />
                </button>
            </List.Item>
        );
    }, [sources]);


    const renderSourceList = useMemo(() => () => {
        const newSources = [...sources];
        if (newSources.length) {
            newSources.push({
                name: 'radius',
                isSelected: false,
                updated: newSources[0].updated,
                nodeCount: 0
            });
        }
        return (
            <Card title="Sources">
                <List
                    size="small"
                    dataSource={newSources}
                    renderItem={renderItem}
                    split={false}
                />
            </Card>
        );
    }, [sources]);
  • Вопрос задан
  • 167 просмотров
Пригласить эксперта
Ответы на вопрос 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Вы уверены, что вы понимаете как работает вызов useMemo? Он в вашем случае возвращает render функцию, которая вызывается каждый раз и пересчитывается только если свойство sources изменилось. Более того в renderItem свойство sources даже не используется, так что вы и заметить ничего не должны.
В таком виде в каком используете useMemo вы, его использовать бессмысленно. Уместней просто вынести эти функции как отдельные компоненты. Либо вынести только renderItem, а renderSourceList переписать так:
renderSourceList = useMemo(() => {
  if (newSources.length) {
    // ...
  }
  return (
    // ...
  );
});

Тогда будете получать меморизированное значение. Но это уместно только если компонент часто перерисовывается, а список при этом не меняется.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы