StarWarsAPI : 2021.02.04 Using Higher-Order-Component ? or Seperate Container Components

오범준·2021년 2월 24일
0

What is the Issue ?

there are two main contents I want to display

1) rockets
2) ships

ex. /ship/shipId
ex. /rocket/rocketId

both will have same form of display, same functions( ex. dispatch )

1st. HOC ?

> HOC

import React ,{useCallback, Component} from 'react';
import { useSelector, useDispatch } from 'react-redux'

const SingleContentHOC = (Component, data) => {

	// some dispatch related functions, 
    // and pass that to Component through props
    
    return  <Component/>
}

export default SingleContentHO

Ship

import React from 'react'
import SingleContentHOC from './SinglePageHOC'

function Ship() {
    return (
        <div>
            
        </div>
    )
}

const EnhancedShip = SingleContentHOC(Ship)

export default EnhancedShip

Rocket

import React from 'react'
import SingleContentHOC from '../containers/SingleContentHOC'

const Rocket = (SingleContent) => {
    return (
        <div>
            
        </div>
    )
}

const EnhancedRocket = SingleContentHOC(Rocket)

export default EnhancedRocket

Is it right approach ?

No !
They both are using 'dispatch' functions itself,
but the problem is they are using 'different dispatch functions'

ex. ship : dispatch functions related with 'ship'
ex. rocket : dispatch functions realted with 'rocket'

2 different Container Components, 1 common Presentational Component

SingleShip : Container Component
import React,{memo} from 'react'
import {useQuery , gql } from '@apollo/client' 
import PhotoGrid from '../../components/PhotoGrid'

const ShipSingleContainer = memo(({match}) => {

    let contentId = match.params.shipId
    let shipId, image, shipName, roles, shipType, typeName ;

    const { loading, error, data } = useQuery(SINGLE_SHIP, {
        variables: { id: contentId },
    });

    console.log("data", data)

    // 여기에 redux 관련 요소 넣기 


    if (loading) return <p>Loading ...</p> 
    else{
        shipId = data.ship.ship_id
        image = data.ship.image 
        shipName = data.ship.ship_name 
        roles = data.ship.roles 
        typeName = data.ship.__typename
    }

    return (
        <div className = "SingleContent" >
            <div>
                <PhotoGrid id = {shipId} img = {image} contentType = {typeName} /> 
            </div>
            <div>
                <h1>Hello {shipName && shipName}!</h1>
            </div>
        </div>

    );
    
})

export default ShipSingleContainer

const SINGLE_SHIP = gql`
    query SingleShip($id : String!){
    ship(id : $id){
        ship_id
        ship_type
        ship_name
        image
        roles
        year_built
        successful_landings
    }
}` 

RocketSingleContainer : Container Component
import React , {memo , useEffect, useState } from 'react'
import {useQuery , gql } from '@apollo/client' 
import PhotoGrid from '../../components/PhotoGrid'
import SinglePageComponent from '../../components/SinglePage'

const RocketSingleContainer = memo(({match}) => {

    let rocketId , image , rocketName, rocketType, typeName ;

    const { loading, error, data } = useQuery(SINGLE_ROCKET, {
        variables: { id: match.params.rocketId }
    });
 

    if (loading && !data ) return <p>Loading ...</p>;
    else{
        rocketId = data.rocket.rocket_id
        image = data.rocket.flickr_images[0] 
        rocketName = data.rocket.rocket_name 
        // roles = data.rocket.roles 
        typeName = data.rocket.__typename
    }


    // 여기에 redux 관련 요소 넣기

    return (
        <SinglePageComponent 
            id = {rocketId}
            img ={image}
            contentType = {typeName}
            name = {rocketName}
        />
    )
    
})

export default RocketSingleContainer

const SINGLE_ROCKET = gql`
    query SingleRocket($id : String!){
    rocket(id : $id){
        id
        rocket_id
        rocket_name
        rocket_type
        description
        flickr_images
        success_rate_pct
    }
}` 

SingleContent : 1 common Presentational Component
import React , { Component } from 'react'
import PhotoGrid from './PhotoGrid'

const SinglePageComponent = ({ id, img, contentType, name }) => {

    return (
        <div className = "SingleContent" >
            <div>
                <PhotoGrid id = {id} img = {img} contentType = {contentType} /> 
            </div>
            <div>
                <h1>Hello {name && name}!</h1>
            </div>
        </div>
    )
}

export default SinglePageComponent
profile
Dream of being "물빵개" ( Go abroad for Dance and Programming)

0개의 댓글