0

I'm trying to rewrite a React class component into a functional hooks-based component, but i cannot figure out how to do it. The component logic and JSX looks something like this:

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]}
            />
</>)

Where the function i'm currently rewriting is onClearSearchBox:

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

I tried naively rewriting it using hooks which turned the setState into this:

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

This does not work and i do not know how to restructure the code, as i cannot call hooks inside a non-React component function. Moving it into the React component function as an inner function does not work either.

The error message i'm getting is:

Uncaught Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component...

I believe my mindset is still stuck to the class-based structure, as i cannot figure out how i would go about and refactoring the LeftPanel. How should i go about refactoring _onClearSearchBox to make it work with hooks?

4
  • You cannot use hooks within a class component, use a functional component instead. Commented Jun 4, 2019 at 10:48
  • Yes that is the whole point of this post. Please read what i'm actually writing Commented Jun 4, 2019 at 10:50
  • you cannot call hooks within a method or a function within the component, It has to be declared at the top level. Commented Jun 4, 2019 at 10:52
  • Yes i know. But the Searchbox component requires a function to use when user clicks on the X mark. I have to feed it a function. And previously that function was just a setState that reset the item list. This does not work with hooks Commented Jun 4, 2019 at 10:57

1 Answer 1

1

useEffect is the wrong hook for this, from the docs:

If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.

In your example, you need control over when to want to call the code e.g. on a button click. I'd say useCallback would be the most appropriate hook here:

const onClearSearchbox = useCallback(() => {
  setMenuItemsFullList(props.items);
}, [props.items]);
...
<SearchBox onClear={onClearSearchBox} ... />
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.