Использование хуков во вложенных функциях - PullRequest
0 голосов
/ 04 июня 2019

Я пытаюсь переписать компонент класса React в функциональный компонент на основе перехватчиков, но не могу понять, как это сделать.Компонентная логика и JSX выглядят примерно так:

export class LeftPanel extends React.Component<ILeftPanelProps, ILeftPanelState> {

const [menuItemsFullList, setMenuItemsFullList] = useState([{links: []}] as any[]);

useEffect(() => {
    const { links } = props;

    setMenuItemsFullList(links);
}, props.links);
....

return (<>
        <SearchBox
            onChange={_onSearch}
            onClear={_onClearSearchBox}
        />
            <NavList
                listEntries={[menuItems]}
            />
</>)

Где функция, которую я сейчас переписываю, это onClearSearchBox:

private _onClearSearchBox() {
    this.setState({ menuItems: { ...this.state.menuItemsFullList } });
}

Я попытался наивно переписать ее, используя хуки, которые превратили setStateв это:

function onClearSearchBox() {
     useEffect(() => setMenuItems(menuItemsFullList));
}

Это не работает, и я не знаю, как реструктурировать код, так как я не могу вызывать перехватчики внутри не-React компонентной функции.Перемещение его в функцию компонента React как внутренней функции также не работает.

Я получаю сообщение об ошибке:

Uncaught Invariant Violation: Invalid hook call.Хуки могут быть вызваны только внутри тела компонента функции ...

Я считаю, что мое мышление все еще привязано к структуре на основе классов, так как я не могу понять, как бы я поступил ирефакторинг левой панели.Как я должен пойти о рефакторинге _onClearSearchBox, чтобы заставить его работать с хуками?

1 Ответ

1 голос
/ 04 июня 2019

useEffect - неправильная ловушка для этого, из документов:

Если вы знакомы с методами жизненного цикла класса React, вы можете думать о useEffect Hook как о componentDidMount, componentDidUpdate и componentWillUnmount вместе взятых.

В вашем примере вам нужно контролировать, когда вы хотите вызвать код, например, по нажатию кнопки.Я бы сказал, что useCallback будет наиболее подходящим хуком здесь:

const onClearSearchbox = useCallback(() => {
  setMenuItemsFullList(props.items);
}, [props.items]);
...
<SearchBox onClear={onClearSearchBox} ... />
...