0

I am using React Native to dynamically render components. Currently the data is being taken by mapping over an array of objects which looks similar to:

const OBJECTS = [
{name: "Object 1", logo: require('../logos/object1.png')},
{name: "Object 2", logo: require('../logos/object2.png')},
{name: "Object 3", logo: require('../logos/object2.png')},
]

I then map over these objects to render a card for each object like so:

<View>
  {object.map(item => {
    return (
    <View key={item.key}>
      <Card>
        <Text>{item.name}</Text>
        <Image source={item.logo}/>
      </Card>
    </View>
        );
      })}
</View>

However now I would like to add additional items to each card which are taking information fetched from an API and retrieved in JSON form. These JSON objects look similar to the following:

Request 1:

fetchPriceActionCreator {
  "items": [{
      "objectId": "object1",
      "price": 10
    },
    {
      "objectId": "object2",
      "price": 5
    },
    {
      "objectId": "object3",
      "price": 20
    }
  ]
}

Request 2:

fetchBalanceActionCreator {
  "items": [{
      "objectId": "object1",
      "balance": 2,
      "account": 30022
    },
    {
      "objectId": "object2",
      "balance": 4,
      "account": 40035
    },
    {
      "objectId": "object3",
      "balance": 6,
      "account": 50021
    }
  ]
}

As the application is growing in complexity, you may notice from the action creators used to make the requests that I have begun to use Redux. My challenge is now figuring out a way to associate the retrieved JSON information, with the initial OBJECTS object array so that I can include this information in the relevant dynamically rendered card displaying the name, logo, balance, and price of each object.

From what I understand, I need to take the static information from the OBJECTS object array, and move this to initialState in either the reducer or store - however I am completely lost as to how to go about doing this, and how to then associate the two retrieved JSON object arrays, with the OBJECT object array.

The end result should look something like this:

<View>
  {object.map(item => {
    return (
    <View key={item.key}>
      <Card>
        <Text>{item.name}</Text>
        <Image source={item.logo}/>
        <Text>{item.price}</Text>
        <Text>{item.balance}</Text>
      </Card>
    </View>
        );
      })}
</View>

Any help would be greatly appreciated.

EDIT:

Currently my redux reducers look like so:

function priceReducer(priceState = {}, action) {
  switch (action.type) {
    case REQUEST_PRICE:
      return Object.assign({}, priceState, {
        isFetching: true,
        didInvalidate: false,
      });
    case RECEIVE_PRICE:
      return Object.assign({}, priceState, {
        isFetching: false,
        didInvalidate: false,
        lastUpdated: action.lastUpdated,
        items: action.items,
      });
    default:
      return Object.assign({}, priceState);
  }
}

1 Answer 1

1

in your redux store you can update the state by through merging the initial state and the data coming from the api, like so

const priceState = {
    // some other props
    OBJECTS: [
        { name: "Object 1", logo: require('../logos/object1.png') },
        { name: "Object 2", logo: require('../logos/object2.png') },
        { name: "Object 3", logo: require('../logos/object2.png') },
    ]  // your initial Data as you posted.
}

function priceReducer(priceState = {}, action) {
    switch (action.type)
    {
        case REQUEST_PRICE: {
            return {
                ...priceState,
                didInvalidate: false,
                isFetching: true,
                OBJECTS: priceState.OBJECTS.map((obj) => {
                    const i = action.items.find((item) => item.objectId == obj.name) || {}; // using the conditional operator to avoid runtime error if no item was found for the given object

                    // Example: current object name is "object1", i will the item inside the payload that will have the its objectId equal to "object1"
                    return {
                        ...obj,
                        ...i /// i will be the item inside the payload that has the same object id as the current object name 
                    }

                })

            }
        }

        case RECEIVE_PRICE: {
            return {
                ...priceState,
                didInvalidate: false, 
                lastUpdated: action.lastUpdated,
                OBJECTS: priceState.OBJECTS.map((obj) => {
                    const i = action.items.find((item) => item.objectId == obj.name) || {}; // using the conditional operator to avoid runtime error if no item was found for the given object

                    // Example: current object name is "object1", i will the item inside the payload that will have the its objectId equal to "object1"
                    return {
                        ...obj,
                        ...i /// i will be the item inside the payload that has the same object id as the current object name 
                    }

                })

            }
        }

     default: return priceState;
    }

}

if you are not sure what the ... is its called the spread operator., which is equivalent to Object.assign that you were using

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

6 Comments

Thank you! I'm new to Redux, how would I go about implementing? Currently my redux looks like: function priceReducer(priceState = {}, action) { switch (action.type) { case REQUEST_PRICE: return Object.assign({}, priceState, { isFetching: true, didInvalidate: false, }); case RECEIVE_PRICE: return Object.assign({}, priceState, { isFetching: false, didInvalidate: false, lastUpdated: action.lastUpdated, items: action.items, }); default: return Object.assign({}, priceState); } }
I have edited the original post with the above as a snippet to make it easier for you to read :)
i have updated my answer to refelect on the code you wrote
It returns the following error TypeError: Undefined is not an object (evaluating 'priceState.ASSETS.map')
what is your key name for the variable OBJECTS
|

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.