ODelibalta
ODelibalta

Reputation: 2254

React Native update multidimensional state value on switch press

Basically I have a list of access levels. I've put them in a list and right side of each list item I have a switch. What I am trying to achieve is to have the onPress event to update my state where the key is of the list item that has been pressed.

Section of the list data. I have no control over the key names. Sorry about that.

accessList:
Array(51)
0:
{FormID: 101, FormName: "ApplicationSettingCheckStoreID", FormDesc: "Activate Device", IsShow: true, Note: "ApplicationSettingCheckStoreID"}
1:
{FormID: 145, FormName: "GiftCardAddFundList", FormDesc: "Add Fund", IsShow: true, Note: "Add Fund"}

The way I render it

 <List>
    {
         this.state.accessList.map( (v, k) => {
            return (
               <ListItem key={v.FormID}>
                  <Row>
                     <Col size={80}>
                        <Text>{v.FormDesc}</Text>
                     </Col>
                     <Col size={20}>
                        <Switch  
                          value={v.IsShow}
                          onValueChange={() => this._switchToggled(v)} />
                      </Col>
                  </Row>
               </ListItem>
            );
         })
     }
   </List>

this is the part I am trying to fill correctly but I've failed multiple times.

  _switchToggled = (listItem) => { 
       ...
  }

I'd really appreciate any help. Thank you.

Upvotes: 0

Views: 190

Answers (1)

Parker Ziegler
Parker Ziegler

Reputation: 1020

What are you using for state management i.e. how is your accessList collection being stored? If it's coming from redux, you could pass an action with the index of the item you want to update like so:

_switchToggled = (listItem, index) => {

  this.props.dispatch(actions.updateToggle({ index, IsShow: !listItem.isShow });
}

Your actions.js file would look something like this:

const updateToggle = (payload) => {
  return {
    type: "UPDATE_TOGGLE",
    payload
  };
};

Your reducer would look something like this:

const reducer = (state, action) => {
  case "UPDATE_TOGGLE":

    // create a copy of the data
    let clone = state.accessList.slice();

    // mutate the single item
    let item = clone[action.payload.index];

    let newItem = {
       ...item,
       IsShow: action.payload.isShow
    };

    // splice it into the clone
    let newAccessList = clone.splice(action.payload.index, 1, newItem);

    return {
      ...state,
      accessList: clone
    };

  default:
   return state;
};

So in your reducer you actually make a copy of your data structure to operate on. This keeps the principle that Redux should never mutate state directly but rather return a new representation of state. Having access to the indices of your accessList array is helpful and allows you to perform the splice and return the item with it's isShow state updated. Let me know if I can help you out any more with this example.

Upvotes: 1

Related Questions