1

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?

2
  • can i see your reducers ? Commented Oct 27, 2017 at 14:56
  • As Aaqib mentioned, you could have defaults available in the reducers. A shot in the dark: <Footer data={this.props.foxFooterData ? this.props.foxFooterData.data[0] : [{}]} /> Commented Jan 7, 2019 at 20:14

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I think I know what you mean, would be able to show me a quick example please?
0

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} />

  }

}

9 Comments

The props in the first iteration is undefined hence the initial check. Do you have any suggestions to get around this and map the data as props like you are suggesting?
Not sure what you mean by "the first iteration". What does your reducer look like?
"the first iteration" is referring to when React loads the component on page load. To clarify, on page load, React runs the component code twice; the first time with empty props fields before the data has been successfully fetched from the API, which is what's causing the 'undefined' error. I think it's more of how React loads components rather than what OP has coded above. I've come across this before and have used a similar 'if' condition as OP to get around the issue. I'm wondering if anyone has a cleaner or simpler solution to this?
I'm still not 100% clear on your problem. Is it that you need to set a default value for these props for the period between when the component first mounts to when the store is populated with the response to the API call? If so, you can set default values in a number of ways: 1. using initialState as the default argument to your reducer (function reducer(state = initialState, action) {}) 2. using default arguments in your component, as in my example above 3. using a check in your selectors, which is what I think you're trying to do in the question.
See redux docs for using initialState redux.js.org/docs/basics/Reducers.html
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.