Filth
Filth

Reputation: 3228

React + Redux Fetch Data - Clean solution

I have a feeling there is a better / non repeatable way of fetching data from props.

Currently I'm mapping elements to props to get data like so:

@connect((store) => {
    return {
        listAdProductsData: store.listAdProductsData.data,
        adProductsData: store.adProductsData.data,
        foxFooterData: store.foxFooterData.data
    }

})

To fetch data associated to the property I'm having to write a "getData" function within my container to check if the data is undefined as an array of objects to then pass down as props to my components like so:

getFoxData(){
        let data;

        if (this.props.foxFooterData.data === undefined) {
            data = [{}];
        } else {
            data = this.props.foxFooterData.data[0];
        }

        return data
    }

With this approach, I will need to write this function a further three two times to fetch data from listAdProductData and adProductsData.

Action to get data:

componentWillMount() {
        //Fetch Fox Footer Data
        this.props.dispatch(fetchFoxFooterData());
    }

Here is what my render function looks like including passing the data down as props:

render() {
        this.getFoxData();

        return (
            <div className="ad-products-wrap container no-padding col-xs-12">
                <Footer data={this.getFoxData()} />

This seems laborious and repeating - surely there has to be a better approach to something like this?

Upvotes: 1

Views: 461

Answers (2)

Marc Davies
Marc Davies

Reputation: 266

Use initialState to make sure you never have undefined entries in your store:

// reducer.js

...

const initialState = {
  listAdProductsData: {
    data: [{}]
  },
  adProductsData: {
    data: [{}]
  },
  foxFooterData:  {
    data: [{}]
  }
}

const reducer(state = initialState, action) {
  switch(action.type) {
...

An alternative approach could be to leave undefined entries in the store then use default values when you destructure props in your components:

// in a functional component

const Component = ({
  listAdProductsData = [{}],
  adProductsData = [{}],
  foxFooterData = [{}]
}) => (
  <Footer data={foxFooterData} />
)

// extending React.Component

class Component extends React.Component {

  render = () => {

    const {
      listAdProductsData = [{}],
      adProductsData = [{}],
      foxFooterData = [{}]
    } = this.props

    return <Footer data={foxFooterData} />

  }

}

Upvotes: 0

Alex Eggers
Alex Eggers

Reputation: 378

Could you not just pass in the particular prop you want the data from as an argument, seeing as the approach seems to be the same for each type of data?

EDIT see comment:

function getData(dao){
    if (dao.data === undefined) {
        return [{}];
    }
    return dao.data;
}

It feels like a very general "null check" so to speak, so you can outsource that to another method and simply pass the object you are trying to fetch the data from. I'm sure it could be done better and more throuroughly with checking for the correct object and all that, but this is the basic idea.

Upvotes: 2

Related Questions