4

I want to export function from one of my functional component that is using hooks to another one. I want to prevent redundant code appearing in my components.

I have tried to create separate function.js file where I wanted to place some of my functions but useDispatch hook makes it impossible as it throws hell a lot of errors in every attempt to make it work. I was searching for solution and trying some export statements in different combinations.

What I want to do is to export my toggleDrawer function from Layout component to other components and here's my code. I'm sure it's very easy and I'm missing something.

import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import Header from '../Header/header'
import DrawerItems from '../DrawerItems/drawerItems'
import { REDUCERS } from '../../Config/config'

import Container from '@material-ui/core/Container'
import Drawer from '@material-ui/core/Drawer'
import { makeStyles } from '@material-ui/core/styles'

const useDrawerStyles = makeStyles({
    paper: {
        width: '175px',
        padding: '10px'
    }
})

const Layout = props => {
    const { isDrawerOpened } = useSelector(state => {
        return {
            ...state.interface_reducer
        }
    })
    const dispatch = useDispatch()
    const drawerClasses = useDrawerStyles()

    const toggleDrawer = (side, open) => event => {
        if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {
            return null
        }

        dispatch({
            type: REDUCERS.TOGGLE_DRAWER,
            payload: open
        })
    }

    return (
        <Container>
            <React.Fragment>
                <Header/>
                <Drawer classes={{paper: drawerClasses.paper}} open={isDrawerOpened} onClose={toggleDrawer('left', false)} >
                    <DrawerItems/>
                </Drawer>
                { props.children }
            </React.Fragment>
        </Container>
    )
}

export default Layout
2
  • A few options: have dispatcher as parameter (and bind the correct arguments in a lambda, you're already doing this then it won't hurt). Define your custom hook (not something I'd do here). Just extract the common logic and share that, event handlers are seldom shared but some of their logic might be. In general: do not overthink the "no duplication" guideline, sometimes it just does not make sense. Also I'd check the onClose logic, it is more convoluted than it should be...you're calling a function to return the handler...it might be a lambda for the handler itself Commented Sep 19, 2019 at 10:56
  • @AdrianoRepetti onClose is correct, it's doesn't fire on render, i have checked, it's only a prop passed to Drawer component. Commented Sep 19, 2019 at 11:08

1 Answer 1

2

Define the function in another file. Or define it in that file and export it. Then you can import it in other files for other components.

Sign up to request clarification or add additional context in comments.

8 Comments

I have tried this but dispatch hook gives errors saying that I have violated hooks rules and it can be only used in functional component.
Ah ok, and so I have another question: Do you want this function, that you're calling from anywhere, to affect the state of this component? Or to affect the state of the component you're calling it in?
The easiest solution is, once the function is defined in your functional component as you have it above, define a global function on the window object. window._toggleDrawer_ = toggleDrawer; And then you can call window._toggleDrawer_(); from anywhere.
Yup it's supposed to affect this specific Drawer component. To visualize problem it's SideNav menu and I want to close it from some other components. I have solution for my specific problem because elements that are supposed to close SideNav are this element children and i can pass this function by props to <DrawerItems toggleDrawer={toggleDrawer}/>, just like that. But i want to share functions between components without passing them with props.
Considering that you're using redux, surely the solution isn't to have a global function that anything can call, but to just use a Redux action right?
|

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.