Home > OS >  Use a function in several react components to manipulate redux store (shared code)
Use a function in several react components to manipulate redux store (shared code)

Time:06-22

I'm currently a bit stuck. Below you'll find a piece of code to update some data in the redux store from a function. That works wel and all is ok.

const handleCBLabelText = (position: string, text: string) => {
    dispatch({
        type: 'CB_LABEL_TEXT_ADD_FOR_POSITION',
        cbLabelStation: position,
        cbLabelText: text
    })
    setTimeout(() => {
        dispatch({
            type: 'CB_LABEL_TEXT_REMOVE_FOR_POSITION',
            cbLabelStation: position
        })
    }, 1500)
}

My Problem is, that I need that piece of code in 5 Components. One of the clean code principles say DRY: Don't repeat yourself. So I thought 'm a genious and make some sort of Utility file with all shared code inside. But as unexperienced react developer I run into a Problem:

Line 4:18:  React Hook "useDispatch" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function  react-hooks/rules-of-hooks

How can I achieve this one? I have also searched for react-hooks/rules-of-hooks but I did not found a solution for it. Thank you guys.

Edit: Here's the shared.ts code

import {useDispatch} from "react-redux";
export {handleCBLabelText}

const dispatch = useDispatch();


const handleCBLabelText = (position: string, text: string) => {
    dispatch({
        type: 'CB_LABEL_TEXT_ADD_FOR_POSITION',
        cbLabelStation: position,
        cbLabelText: text
    })
    setTimeout(() => {
        dispatch({
            type: 'CB_LABEL_TEXT_REMOVE_FOR_POSITION',
            cbLabelStation: position
        })
    }, 1500)
}

CodePudding user response:

You would write a thunk for this:

const handleCBLabelText = (position: string, text: string) => dispatch => {
    dispatch({
        type: 'CB_LABEL_TEXT_ADD_FOR_POSITION',
        cbLabelStation: position,
        cbLabelText: text
    })
    setTimeout(() => {
        dispatch({
            type: 'CB_LABEL_TEXT_REMOVE_FOR_POSITION',
            cbLabelStation: position
        })
    }, 1500)
}

and then later call it like dispatch(handleCBLabelText("somePosition", "someText")) in your component - that way you can call the useDispatch hook in your component.


Generally, just so you aware: you are writing a very outdated style of Redux here - modern Redux does not have ACTION_TYPES - and it also does not use switch..case reducers, immutable reducer update logic or setup with createStore/applyMiddleware/compose/combineReducers. It is about 1/4 of the code as a consequence. I would highly recommend you to read Why Redux Toolkit is How To Use Redux Today and then follow the official Redux Tutorial

  • Related