Home > Enterprise >  Fire redux dispatch in custom onclick event
Fire redux dispatch in custom onclick event

Time:12-25

I've hunted around but can't seem to find 9or understand) how to achieve this.

I have a button that fires an event on click

<button onClick={TestClick}>Click Me </button>

the TestClick event reads as:

let TestClick = (e) => {
    const Dispatch = useDispatch();
    let Num = Math.random()*10;
    Dispatch(Increment(num));
};

This triggers Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. error.

How do I dispatch within a user function?

import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './actions';

    let TestClick = () => {
        const dispatch = useDispatch();
        let Num = Math.random() * 10;
        dispatch(increment(Num));
    };

function App() {
    const counter = useSelector((state) => state.counter);
    const isLoggedIn = useSelector((state) => state.isLogged);

    const dispatch = useDispatch();

    return (
        <div className="App">
            <h1>Counter {counter}</h1>
            <button onClick={() => dispatch(increment(5))}> </button>
            <button onClick={() => TestClick()}> Random</button>
            <button onClick={() => dispatch(decrement())}>-</button>
            {isLoggedIn ? <h3>Valueable info</h3> : ''}
        </div>
    );
}

export default App;

CodePudding user response:

You can't use hooks outside of React components or another hook.

Two solutions:

const useTestClick = () => {
  const dispatch = useDispatch();
  let num = Math.random() * 10;
  return () => dispatch(increment(num));
};

function App() {
  const testClick = useTestClick()

  /* ... */

  <button onClick={testClick}> Random</button>
function App() {
  const dispatch = useDispatch();

  const testClick = useCallback(() => {
    let num = Math.random() * 10;
    return () => dispatch(increment(num));
  }, [])

  /* ... */

  <button onClick={testClick}> Random</button>

CodePudding user response:

Move the TestClick inside the comnponent. And to keep the handler reference from changing on each render, use useCallback

import { useCallback, useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './actions';

function App() {
    const counter = useSelector((state) => state.counter);
    const isLoggedIn = useSelector((state) => state.isLogged);

    const dispatch = useDispatch();

    const TestClick = useCallback(() => {
        let Num = Math.random() * 10;
        dispatch(increment(Num));
    }, []);

    return (
        <div className="App">
            <h1>Counter {counter}</h1>
            <button onClick={() => dispatch(increment(5))}> </button>
            <button onClick={TestClick}> Random</button>
            <button onClick={() => dispatch(decrement())}>-</button>
            {isLoggedIn ? <h3>Valueable info</h3> : ''}
        </div>
    );
}

export default App;
  • Related