0

I have two components in first component I created the function "onClick" with difficult logic, the function "onClick" use API and reducer, also use other functions. I need use function "onClick" in second component, but I don't how to do this better. Can you help me please?

import React, { useEffect } from 'react';
import {Switch, Route, Link, Redirect} from 'react-router-dom';
import PageComponent_1 from '../page-component-1';
import PageComponent_2 from '../page-component-2';
 
const Application: React.FunctionComponent = () => {
  return (
    <div>
      
      <div>
        <hr />
        <nav>
          <ul>
            <li>
              <Link to="/PageComponent_1">PageComponent_1</Link>
            </li>
            <li>
              <Link to="/PageComponent_2">PageComponent_2</Link>
            </li>
          </ul>
        </nav>
        <hr />
        <Switch>
          <Route exact path={ "/PageComponent_1" } component={ PageComponent_1 } />
          <Route exact path={ "/PageComponent_2" } component={ PageComponent_2 } />
          <Redirect to="/"/>
        </Switch>
      </div>
    </div>
  );
};
 
export default Application;

first component

import React, {useState} from 'react';
 
type Props = {
 
}
 
type State = {
  field_1: string
};
 
const PageComponent_1: React.FunctionComponent<Props> = () => {
 
  const [state, changeState] = useState<State>(
    {
      field_1: '',
    },
  );
 
  const onClick = (e:any, feldName:string) =>{

    //here is difficult logic

    changeState((state) => ({
      ...state,
      [feldName]: 'TEST'
    }));
  }
  
  return (
    <div className="">
 
      PageComponent_1
 
      <div onClick={(e:any)=>onClick(e, 'field_1')}>
        ClickMe
      </div>
    </div>
  );
};
    
export default React.memo(PageComponent_1);

second component

import React, {useState} from 'react';
 
type Props = {
 
}
 
type State = {
  field_2: string
};
 
const PageComponent_2: React.FunctionComponent<Props> = () => {
 
  const [state, changeState] = useState<State>(
    {
      field_2: '',
    },
  );
 
  return (
    <div className="">
      PageComponent_2
    </div>
  );
};
    
export default React.memo(PageComponent_2);
Chips
  • 69
  • 5
  • 1
    Does this answer your question? [Exporting functions with reactjs and babel](https://stackoverflow.com/questions/44309306/exporting-functions-with-reactjs-and-babel) – Mustafa Yousef Jan 21 '22 at 07:50
  • Please share how you are wanting to, or trying to, use the same `onClick` handler in the second component. Does not declaring the handler function in a utility and exporting/importing into both not work for your use case? – Drew Reese Jan 21 '22 at 07:52

1 Answers1

2

You can create the function outside of any component, having it accept the type of the state object as a type parameter and the state setter function to use (changeState in your code) as a parameter:

const onClick = <StateType,>(
    e: any,
    fieldName: keyof StateType,
    changeState: React.Dispatch<React.SetStateAction<StateType>>
) => {

    //here is difficult logic

    changeState((state) => ({
        ...state,
        [fieldName]: "TEST"
    }));
};

Here's how you use it in your current component:

const PageComponent_1: React.FunctionComponent<Props> = () => {

    const [state, changeState] = useState<State>(
        {
            field_1: "",
        },
    );

    const onClickField1 = useCallback((e: any) => onClick(e, "field_1", changeState), []);

    return (
        <div className="">

            PageComponent_1

            <div onClick={onClickField1}>
                ClickMe
            </div>
        </div>
    );
};

Some key bits there:

  • onClick needs to be generic so the state type it's working with comes from where it's used; that's the StateType type parameter.
  • fieldName is keyof StateType so we can use it to set the property in a typesafe manner.
  • changeState (more typically called setState) uses the React type React.Dispatch<React.SetStateAction<T>> where T is a type parameter for the type of the state item (in our case, StateType). (If you ever wonder about the types of things like that, in any decent IDE you can just hover the mouse over the state setter, etc., and the IDE will show you the type.)
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875