mardi 25 octobre 2022

Best way to consolidate state dependent boiler plate in React Functional component

I'm trying to understand if there is a better design pattern to this use case.

I have a react functional component such as this.

const ComponentMajor = (props) => {
   [state, setState]
   classes = useStyles()
   
   //image a whole bunch of other state.
   return (
   <div stateDependentProp1 stateDependentProp2>{stateDependent3}</div>
   <div stateDependentProp1 stateDependentProp2>{stateDependent3}</div>
   <div stateDependentProp1 stateDependentProp2>{stateDependent3}</div>)
   //imagine each of these is maybe 50 lines of code and we need 10 of them.
   //perfect use case for code re use.
}

So naturally I create a div component, but since it's so coupled with ComponentMajor and only needs to be used in ComponentMajor to eliminate code dupl, i want it to live inside the same file.

Option 1

const ComponentMajor = (props) => {
   [state, setState]
   classes = useStyles()
   
   const boilerPlateComp = (props) => <div props>{stateDependent3}</div>
   //image a whole bunch of other state.
   return(
   <boilerPlateComp props/>
   <boilerPlateComp props/>
   <boilerPlateComp props/>)
   
}

This isn't good because every time ComponentMajor re-renders it redeclares boilerPlateComp and has weird behaviors.

Option 2

declare boilerPlateComp OUTSIDE ComponentMajor - but this makes it inefficient to share scope (which if defined inside ComponentMajor is not an issue) between them. It results in some annoying boiler plate ironically to pass the scope dependencies in as props.

The cleanest I was able to come up with was something like this, but there HAS to be a better way to do this in FUNCTIONAL components.

const boilerPlateComp = ({sharedScope, props}) => {
    let {stateDep1, stateDep2, stateDep3, etc} = sharedScope
    return (<div props>{stateDependent3}</div>)
}

const ComponentMajor = (props) => {
   [state, setState]
   classes = useStyles()
   let sharedScope = {state, setState, classes, etc}
   //image a whole bunch of other state.
   return(
   <boilerPlateComp props sharedScope={sharedScope}/>
   <boilerPlateComp props sharedScope={sharedScope}/>
   <boilerPlateComp props sharedScope={sharedScope}/>)

}

My Question Is:

What is the standard design pattern for this common use case? Is this a scenario where a class component would make more sense?

I tried playing around with memoizing the components declared WITHIN ComponentMajor but didn't seem to work.

Is there a clean way to use javascript apply to pass the scope onto the component instances?

Aucun commentaire:

Enregistrer un commentaire