skip to Main Content

I am having a hard time coming up with a good approach for splitting business logic from a component. Due to different use cases, it has gotten too complicated and resulted in a long file. I’ve been attempting to split the logic in diferent hooks with the idea of activating each of them individually. I am worried that if I keep adding more hooks, I am going to overload the App. These hooks have functionality that is causing frequent re-renders and other than passing flags to have them stop them from running to a certain extent, I cant think of a better way of doing this other than moving the hooks one level above which i wanted to avoid because i wanted to keep map logic within the map itself to avoid issues related to fetching google api data.

Is there a better way to structure the use of hooks while keeping them in the same place?

What i have is more or less like this. Data A and B represent different google map elements.

const App = ( {modality} ) => 
{ 
   const dataA = useHookA(); 
   const dataB = useHookB(); 

   let data;
    switch ( modality)
    {
      case 'A':
        data = dataA;
        break;
      case 'B':
        data = dataB;
        break;
     }

    return <GoogleMap>{data}</GoogleMap>
};

2

Answers


  1. Instead of maintaining 2 logics, states, etc… when you only need one, create 2 map components, and switch between them:

    const MapA = () => {
      const data = useHookA();
      
      return <GoogleMap>{data}</GoogleMap>
    }
    
    const MapB = () => {
      const data = useHookB();
      
      return <GoogleMap>{data}</GoogleMap>
    }
    
    const App = ({ modality }) => modality === 'A'
      ? <MapA />
      : <MapB />;
    

    You can also create a map component generator function that accepts a hook, and returns a component to make it more DRY.

    const createMapComponent = useHook => () => (
      const data = useHook();
    
      return <GoogleMap>{data}</GoogleMap>
    );
    
    const MapA = createMapComponent(useHookA);
    
    const MapB = createMapComponent(useHookB);
    
    Login or Signup to reply.
  2. I just see that you are writing bad React. You should not be running arbitrary code within the body of a component, which is going to affect the state of the component, without putting that logic inside a hook of some sort.

    The code you currently have is equivalent to having a useEffect with an undefined dependency array, and this useEffect is changing the state, well of course you’ll get frequent re-rendering!

    See if the following reduces your rendering problems otherwise the other answer is pretty good:

    const App = ( {modality} ) => {
       const dataA = useHookA();
       const dataB = useHookB();
       const data = useMemo(() => {
          switch (modality) {
             case 'A':
                return dataA;
             case 'B':
                return dataB;
             default:
                return undefined;
          }
       }, [modality]);
    
       return <GoogleMap>{data}</GoogleMap>
    };
    

    The dependency list for useMemo could also include dataA and dataB, if you expect them to change frequently and you want those changes to affect the state of the component. Otherwise, the list with just modality is fine.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search