简体   繁体   中英

Validation of fetched data from API Redux React

So, I will go straight to the point. I am getting such data from api:

[
{
    id: 123,
    email: asd@asd.com
},
{
    id: 456,
    email: asdasd.com
},
{
    id: 789,
    email: asd@asd
},
...

]

and I should validate email and show this all info in a list, something like this:

  1. asd@asd.com - valid
  2. asdasd.com - invalid
  3. asd@asd - invalid ...

My question is what is the best way to store validation data in a store? Is it better to have something like "isValid" property by each email? I mean like this:

store = {
emailsById: [
    123: {
        value: asd@asd.com,
        isValid: true
    },
    456: {
        value: asdasd.com,
        isValid: false
    },
    789: {
        value: asd@asd,
        isValid: false
    }
    ...
]

}

or something like this:

store = {
emailsById: [
    123: {
        value: asd@asd.com
    },
    456: {
        value: asdasd.com
    },
    789: {
        value: asd@asd
    }
    ...
],
inValidIds: ['456', '789']

}

which one is better? Or maybe there is some another better way to have such data in store? Have in mind that there can be thousands emails in a list :)

Thanks in advance for the answers ;)

First of all, the way you defined an array in javascript is wrong. What you need is an array of objects like,

 emails : [ { id: '1', email: 'abc@abc.com', isValid: true }, { id: '2', email: 'abc.com', isValid: false; } ]; 

if you need do access email based on an id, you can add an id property along with email and isValid. uuid is a good way to go about it.

In conclusion, it depends upon your use case.

I believe, the above example is a good way to keep data in store because it's simple.

What you described in your second example is like maintaining two different states. I would not recommend that.

So your best option would be to create a separate file that will contain all your validations methods. Import that into the component you're using and then when you want to use the logic for valid/invalid.

If its something that you feel you want to put in the store from the beginning and the data will never be in a transient state you could parse your DTO through an array map in your reducer when you get the response from your API.

export default function (state = initialState, action) {
    const {type, response} = action

    switch (type) {
        case DATA_RECIEVED_SUCCESS:
            const items = []

            for (var i = 0; i < response.emailsById.length; i++) {
                var email = response.emailsById[i];

                email.isValid = checkEmailValid(email)

                items.push(email)
            }

            return {
                ...state,
                items
            }
    }
}

However my preference would be to always check at the last moment you need to. It makes it a safer design in case you find you need to change you design in the future. Also separating the validation logic out will make it more testable

I recommend reading the article " Avoiding Accidental Complexity When Structuring Your App State " by Tal Kol which answers exactly your problem: https://hackernoon.com/avoiding-accidental-complexity-when-structuring-your-app-state-6e6d22ad5e2a

Your example is quite simplistic and everything really depends on your needs but personally I would go with something like this (based on linked article):

var store = {
  emailsById: {
    123: {
      value: '123@example.com',
    },
    456: {
      value: '456@example.com',
    },
    789: {
      value: '789@example.com',
    },
    // ...
  },
  validEmailsMap: {
    456: true, // true when valid
    789: false, // false when invalid
  },
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM