John Baek John Baek - 26 days ago 8
React JSX Question

Distribute Props to Each Screen

I'm getting this JSON response from API in React Native.

[
{
"cloth_image": "https://ox0%3es",
"id": 7,
"big_cloth_type": "t"
},
{
"cloth_image": "https://qM%3D&",
"id": 8,
"big_cloth_type": "t"
},
{
"cloth_image": "https://qM%",
"id": 9,
"big_cloth_type": "o"
},
{
"cloth_image": "https://qD&",
"id": 10,
"big_cloth_type": "s"
}
]


This response above is stored as this.props.clothesList from Redux.

What I want to do is, if the objects of
big_cloth_type
in the array is
t
, I want to assign them to corresponding Screen. (In this case, it's TopScreen)

From code, (This is render() function)

<View style={{flex: 1}}>
<Tabs initialPage={0}>
<Tab heading={<TabHeading><Text style={styles.tabHeadingStyle}>Tops</Text></TabHeading>}>
<TopScreen clothes={blahblah}/> <----- here I want to pass objects with 't' type to this Screen.
</Tab>
<Tab heading={<TabHeading><Text style={styles.tabHeadingStyle}>Outers</Text></TabHeading>}>
<OutwearScreen clothes={blahblah} /> <--- here the objects with 'o'
</Tab>
<Tab heading={<TabHeading><Text style={styles.tabHeadingStyle}>Bottoms</Text></TabHeading>}>
<BottomScreen />
</Tab>
<Tab heading={<TabHeading><Text style={styles.tabHeadingStyle}>Shoes</Text></TabHeading>}>
<ShoeScreen />
</Tab>
<Tab heading={<TabHeading><Text style={styles.tabHeadingStyle}>ETC</Text></TabHeading>}>
<EtcScreen />
</Tab>
</Tabs>
<FABs
active={this.state.active}
/>
</View>


I can't come up with any solution so far. :(

For the suggestion of the comment, I'm posting my reducer

export default function(state = INITIAL_STATE, action) {
switch (action.type) {
case CLOTHES_LIST_SUCCESS:
return { ...state, clothesList: action.payload }
case CLOTHES_LIST_FAIL:
return { ...state, }
default:
return state;
}
}

Answer Source

Assuming you are using a container/component approach with redux, it would be better to act on the API response in the container and pass it as props to the component

For eg:

let getTrousers = (data) =>{
   return data.filter( (item) => { item. big_cloth_type === 't') } )
}

const mapStateToProps = (state,ownprops) => {
   let apiresponse = state.clothesList;
   let trousers = getTrousers(apiresponse); 
   /*do similarly for different cloth types*/

  return { 
   trousers,
   shoes,
   outerwear,
   tops

   }

}

export default connect(mapStateToProps)(ClothesComponent)

Now in your ClothesComponent , as you had described earlier you can

<View style={{flex: 1}}>
        <Tabs initialPage={0}>
          <Tab heading={<TabHeading><Text style={styles.tabHeadingStyle}>Tops</Text></TabHeading>}>
            <TopScreen clothes={this.props.tops}/> <----- here I want to pass objects with 't' type to this Screen.
          </Tab>
          <Tab heading={<TabHeading><Text style={styles.tabHeadingStyle}>Outers</Text></TabHeading>}>
            <OutwearScreen clothes={this.props.outerwear} /> <--- here the objects with 'o'
          </Tab>
          <Tab heading={<TabHeading><Text style={styles.tabHeadingStyle}>Bottoms</Text></TabHeading>}>
           <BottomScreen />
          </Tab>
          <Tab heading={<TabHeading><Text style={styles.tabHeadingStyle}>Shoes</Text></TabHeading>}>
            <ShoeScreen />
          </Tab>
          <Tab heading={<TabHeading><Text style={styles.tabHeadingStyle}>ETC</Text></TabHeading>}>
            <EtcScreen />
          </Tab>
        </Tabs>
        <FABs
          active={this.state.active}
        />
      </View> 

Doing your data manipulation in the container ,instead of the component has it advantages . Primarily it keeps your component 'dumb' i.e it performs only rendering with the given data and not anything else.

I'd recommend reading React with Redux and smart vs dumb components by Dan . This should clear a lot of things up !