简体   繁体   中英

React Native Redux - How to Update an Item in an Array?

I am a newbie with React Native and Redux, building a quiz app now.

I want to update an item (name) in an array. Could somebody let me know what is wrong with my following code:

export const setName = name => ({
  type: "ADD_NAME",
  id: 1,
  name: name
});

INITIAL_STATE = [
  {
    id: 1,
    question: "documentary",
    answers: [
      { id: "1", text: "記録映画" },
      { id: "2", text: "理科" },
      { id: "3", text: "自由" },
      { id: "4", text: "形" }
    ],
    name: 0
  },
  {
    id: 2,
    question: "cozy",
    answers: [
      { id: "1", text: "居心地の良い" },
      { id: "2", text: "関係する" },
      { id: "3", text: "ブレーク" },
      { id: "4", text: "車" }
    ],
    name: 0
  },
  {
    id: 3,
    question: "utmost",
    answers: [
      { id: "1", text: "最大限" },
      { id: "2", text: "疑問に思う" },
      { id: "3", text: "昨日" },
      { id: "4", text: "まだ" }
    ],
    name: 0
  }
];

const reducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case "ADD_NAME":
      return state.map((item, index) => {
        if (item.id === 1) {
          return {
            ...item,
            name: ""
          };
        }
        return item;
      });

    default:
      return state;
  }
};

export const reducers = combineReducers({
  user: reducer
});

// store.js
export const store = createStore(reducers);

It worked first when there was just one array. Like this

INITIAL_STATE = { id: 1, question: "documentary", answers: [ { id: "1", text: "記録映画" }, { id: "2", text: "理科" }, { id: "3", text: "自由" }, { id: "4", text: "形" } ], name: 0 }

But it doesn't after adding more arrays and changing the actions and the reducers. This is the rest of code Home.js (container+component)

export class Home extends Component {
  render() {
    return (
      <View style={{flex: 1, justifyContent: 'space-around', alignItems: 'center'}}>
        <Text style={{marginTop: 100}}>My name is {this.props.name}.</Text>
        <View style={{flexDirection: 'row'}}>
          <Button
            onPress={() => this.props.setName(1)}
            title="setName"
          />
          <Button
            onPress={() => this.props.setName('2')}
            title="setName"
          />
        </View>
        <Text style={{marginBottom: 100}}>現在のstore: {JSON.stringify(store.getState())}</Text>
      </View>
    )
  }
}

const mapStateToProps = state => ({
  name: state.user.name
})

const mapDispatchToProps = {
  setName,
  deleteName
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Home)

This should work.

const reducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case "ADD_NAME":
      const { id = 1, name = "" } = action;
      return state.map(item => ({
        ...item,
        name: item.id === id ? name : item.name
      }));
    default:
      return state;
  }
};

It seems like you're not updating the name prop but just set it to an empty string. Also you'd probably pass the item's id and use it for lookup:

export const setName = (name, id) => ({ // pass item's id
  type: "ADD_NAME",
  id,
  name
});

const reducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case "ADD_NAME":
      return state.map(item => {
        if (item.id === action.id) {  // Match the item by id and update its name
          return {
            ...item,
            name: action.name
          };
        }
        return item;
      });

    default:
      return state;
  }
};

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