Home > Net >  React Refactoring component with too many props
React Refactoring component with too many props

Time:10-22

I have a component "Collage", which renders 4 types of images: BANNER, SQUARE, PORTRAIT and POSTER.

function Collage({ banner, square, portrait, poster }) {
   return (
       <View>
           <Image uri={banner?.uri} style={styles.banner} />
           <Image uri={square?.uri} style={styles.square} />
           <Image uri={portrait?.uri} style={styles.portrait} />
           <Image uri={poster?.uri} style={styles.poster} />
       </View>
   );
}

Collage.propTypes = {
    banner: PropTypes.shape({
        uri: PropTypes.string.isRequired
    }),
    square: PropTypes.shape({
        uri: PropTypes.string.isRequired
    }),
    portrait: PropTypes.shape({
        uri: PropTypes.string.isRequired
    }),
    poster: PropTypes.shape({
        uri: PropTypes.string.isRequired
    }),
}

Now, I wanna add the functionality of doing something (different for each image) when pressing the collage images.

Something like:

 <Collage 
    banner={banner}
    onPressBanner={handleOnPressBanner}
    square={square}
    onPressSquare={handleOnPressSquare}
    portrait={portrait}
    onPressPortrait={handleOnPressPortrait}
    poster={poster}
    onPressPoster={handleOnPressPoster}
 />


 ...

 function Collage({ banner, onPressBanner ... }) {
   return (
       <View>
           <TouchableOpacity onPress={onPressBanner}>
              <Image uri={banner?.uri} style={styles.banner} />
           </TouchableOpacity>

           ... repeat for others
       </View>
   );
}

It seems unprofessional code, in my opinion, and there might be a way to make it simpler, with less props and more generalization. Any ideas?

CodePudding user response:

I will extend the comment:

You either want to create the functions inside the Collage component (rather than receive them as props)

Or have an array of images sent to View component. Something like:

function Collage({ images }) {
   return (
       <View>
           images.map(image => (
             <Image key={`collage-image-${image.type}`} uri={image.uri} style={styles[image.type]} onClick={image.onClick} />
           )
       </View>
   );
}

where images is an array, each array element containing an uri, an type (which should be one of banner, square, portrait, poster in your case), and a click handler.

Warning: if you have multiple collages on the same page you might want to send some extra prop in order to ensure that you won't have two children with the same key

  • Related