визуализировать массив объекта из хранилища в моем компоненте и изменить значение в объекте при вызове onPress с помощью диспетчера - PullRequest
0 голосов
/ 22 сентября 2019

Итак, у меня есть фиктивные данные, которые представляют собой массив объектов в качестве исходного состояния.каждый объект имеет значение id, name и checked (логическое и изначально ложное).У меня есть действие, которое отображает этот объект и изменяет проверенное значение на true, учитывая item.id.Затем в моем компоненте я визуализировал эти объекты как touchableOpacity, используя map, а затем onPress отправил это действие.Я помещаю console.log (item.id, 'is', item.checked), чтобы увидеть, изменяется ли значение проверяемого, но оно просто продолжает регистрировать false.

Логика для того, чтобы поменять проверенное значение с ложного на истинное, была первой в редукторе, поэтому я переместил его в действие, но он все еще не работает.

Это редуктор,

const initialState = {
  items: [
    {
      id: 1,
      itemName: 'Plastic',
      checked: false,
    },
    {
      id: 2,
      itemName: 'Papers',
      checked: false,
    },
    {
      id: 3,
      itemName: 'Pet Bottle',
      checked: false,
    },
  ],
};

export default (state = initialState, action) => {
  switch (action.type) {
    case TOGGLE_ITEM:
      return {
        ...state,
        items: action.checked,
      };
    default:
      return state;
  }
};

тогда мое действие:

const toggleItemHelper = (items, itemId) => {
  items.map(item =>
    item.id === itemId ? {...item, checked: !item.checked} : item,
  );
};

export const toggleItemAction = itemId => (dispatch, getState) => {
  const items = getState().items;
  return dispatch({
    type: TOGGLE_ITEM,
    checked: toggleItemHelper(items, itemId),
  });
};

тогда мой компонент

import {toggleItemAction} from '../../../../../redux/GarbageItem/action';

const GarbageItem = () => {
  const Icon = createIconSetFromFontello(fontelloConfig);
  const items = useSelector(state => state.garbageItem.items);
  const dispatch = useDispatch();
  const toggleItem = itemId => dispatch(toggleItemAction(itemId));

  return (
    <View style={styles.garbageItemsContainer}>
      {items.map(item => (
        <TouchableOpacity
          key={item.id}
          style={styles.itemContainer}
          onPress={() => {
            toggleItem.bind(this, item.id);
            console.log(item.id, 'is', item.checked);
          }}>
          <View style={styles.checkBoxContainer}>
            <Text>
              <Icon
                name="uncheckedCheckBox"
                size={20}
                color={colors.gomiGray}
              />
            </Text>
          </View>
          <Text style={styles.itemLabel}>{item.itemName}</Text>
        </TouchableOpacity>
      ))}
    </View>
  );
};

export default GarbageItem;

ожидал, что console.log покажет item.id, 'is', true когданажата touchableOpacity, но затем он продолжает показывать false независимо от того, сколько раз я нажимаю на него.

Я действительно получил совет, что getState является анти-паттерном, поэтому было бы удивительно, если бы я мог изменить значение зарегистрированногоЗатем useSelector отправляет действие, которое заменит старый объект на обновленный.

1 Ответ

0 голосов
/ 22 сентября 2019

Я смог решить эту проблему, переместив логику изменения флажка: ложь в истину в компоненте, а не в действии. Js: D

вот новый код теперь,

редуктор,

const initialState = {
  items: [
    {
      id: 1,
      itemName: 'Plastic',
      checked: false,
    },
    {
      id: 2,
      itemName: 'Papers',
      checked: false,
    },
    {
      id: 3,
      itemName: 'Pet Bottle',
      checked: false,
    },
  ],
};

export default (state = initialState, action) => {
  switch (action.type) {
    case TOGGLE_ITEM:
      return {
        ...state,
        items: action.newItems,
      };
    default:
      return state;
  }
};

действие,

export const toggleItemAction = newItems => dispatch => {
  return dispatch({
    type: TOGGLE_ITEM,
    newItems,
  });
};

index.js

const GarbageItem = () => {
  const Icon = createIconSetFromFontello(fontelloConfig);
  const currentItems = useSelector(state => state.garbageItem.items);
  const dispatch = useDispatch();
  const toggleItem = newItems => dispatch(toggleItemAction(newItems));

  const checkItem = (items, itemId) => {
    return items.map(item =>
      item.id === itemId ? {...item, checked: !item.checked} : item,
    );
  };

  return (
    <View style={styles.garbageItemsContainer}>
      {currentItems.map(item => (
        <TouchableOpacity
          key={item.id}
          style={styles.itemContainer}
          onPress={() => {
            const newItems = checkItem(currentItems, item.id);
            toggleItem(newItems);
            console.log(item.id, 'is', item.checked);
          }}>
          <View style={styles.checkBoxContainer}>
            <Text>
              <Icon
                name="uncheckedCheckBox"
                size={20}
                color={colors.gomiGray}
              />
            </Text>
          </View>
          <Text style={styles.itemLabel}>{item.itemName}</Text>
        </TouchableOpacity>
      ))}
    </View>
  );
};
...