I have several components that I repeat a dispatch in. I want to use a helper function to import and use in multiple components. It's maddening that it's not straight forward - or at least for me. Read a bunch of post about this, but could not relate it.
The issue I get is react-dom.development.js:16227 Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: You might be breaking the Rules of Hooks
How do you call dispatch in a helper function then. I think custom hooks might be the way to go - looking at it right now.
Stripped down Component Example:
...imports...
import { helperCall } from '../../assets/helperFunctions/helperCall';
export default function CompExamp() {
...variables...
return (
<div className="min-w-0 flex-1"
onClick={(e) => helperCall(e, searchText, searchType)}
>
<span className="absolute inset-0" aria-hidden="true" />
<p className="text-sm font-medium text-black">Target</p>
<p className="text-base text-gray-700">test</p>
</div>
)
}
Stripped down Helper Function:
import React from 'react';
import { useDispatch } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import { loadASearchResults, updateASearchTerm } from '../../redux/actionsReducers/AResults';
import { loadBSearchResults, updateBSearchTerm } from '../../redux/actionsReducers/BResults';
import { loadCSearchResults, updateCSearchTerm } from '../../redux/actionsReducers/CResults';
export function helperCall(e: any, searchText: string, searchType: string) {
const dispatch = useDispatch();
const navigate = useNavigate();
e.preventDefault();
e.stopPropagation();
if (!searchText || searchText === '-' || searchText.toLowerCase() === 'not listed') {
return;
}
if (searchType === 'a') {
dispatch(updateASearchTerm({ searchTerm, searchType }));
dispatch(loadASearchResults({ searchTerm, searchType }));
navigate('/page-a');
} else if (searchType === 'b') {
dispatch(updateBSearchTerm({ searchTerm, searchType }));
dispatch(loadBSearchResults({ searchTerm, searchType }));
navigate('/page-b');
} else if (searchType === 'c') {
dispatch(updateCSearchTerm({ searchTerm, searchType }));
dispatch(loadCSearchResults({ searchTerm, searchType }));
navigate('/page-c');
}
}
You can only use React hooks in a React functional component, but you can pass the function to a helper function like so:
import { helperCall } from "../../assets/helperFunctions/helperCall";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
export default function CompExamp() {
const dispatch = useDispatch();
const navigate = useNavigate();
/* variables */
return (
<div
className="min-w-0 flex-1"
onClick={(e) => helperCall(e, searchText, searchType, dispatch, navigate)}
>
<span className="absolute inset-0" aria-hidden="true" />
<p className="text-sm font-medium text-black">Target</p>
<p className="text-base text-gray-700">test</p>
</div>
);
}
import React from 'react';
import { loadASearchResults, updateASearchTerm } from '../../redux/actionsReducers/AResults';
import { loadBSearchResults, updateBSearchTerm } from '../../redux/actionsReducers/BResults';
import { loadCSearchResults, updateCSearchTerm } from '../../redux/actionsReducers/CResults';
export function helperCall(e: any, searchText: string, searchType: string, dispatch: Function, navigate: Function) {
e.preventDefault();
e.stopPropagation();
if (!searchText || searchText === '-' || searchText.toLowerCase() === 'not listed') {
return;
}
if (searchType === 'a') {
dispatch(updateASearchTerm({ searchTerm, searchType }));
dispatch(loadASearchResults({ searchTerm, searchType }));
navigate('/page-a');
} else if (searchType === 'b') {
dispatch(updateBSearchTerm({ searchTerm, searchType }));
dispatch(loadBSearchResults({ searchTerm, searchType }));
navigate('/page-b');
} else if (searchType === 'c') {
dispatch(updateCSearchTerm({ searchTerm, searchType }));
dispatch(loadCSearchResults({ searchTerm, searchType }));
navigate('/page-c');
}
}