Редуктор обновлен с неправильным значением (массив был обновлен одним элементом с несколькими элементами внутри, вместо этого распространяя их) - PullRequest
0 голосов
/ 12 июня 2018

Мне трудно понять это.Есть компонент, который является поисковым фильтром и помещает все выбранные фильтры в URL.Все работает как надо, за исключением случая обновления, в этом случае редуктор обновляется для выбранного фильтра с массивом с одним элементом, в котором у меня есть все выбранные элементы, а не разбитые на массивы.

fe у меня есть url

myexampleapp.com/alltrips?tripType=short_walk,cycling,downhill_cycling,long_walks&season=spring,summer,alle,vinter&lengthTo=50

мой редуктор

// ------------------------------------
// Constants
// ------------------------------------
export const UPDATE_FILTERS = 'UPDATE_FILTERS';

// ------------------------------------
// Actions
// ------------------------------------
const updateFilter = (key, value) => ({
  type: UPDATE_FILTERS,
  payload: {
    key,
    value
  }
});

// ------------------------------------
// Action creators
// ------------------------------------
export const updateFilterState = (key, value) => {
  return dispatch => {
    dispatch(updateFilter(key, value));
  };
};

// ------------------------------------
// Reducer
// ------------------------------------
const initialState = {
  tripType: [],
  season: [],
  tripsTo: undefined,
  tripsFrom: undefined
};

export function filterReducer (state = initialState, action) {
  switch (action.type) {
  case UPDATE_FILTERS: {
    const key = action.payload.key;
    const value = action.payload.value;

    if (key === 'tripsFrom' || key === 'tripsTo') {
      return Object.assign({}, state, { [key]: value });
    } else {
      var newFilter = state[key].slice();
      var ttIdx = state[key].indexOf(value);

      if (ttIdx !== -1) {
        newFilter.splice(ttIdx, 1);
      } else {
        newFilter.push(value);
      }
    }
    console.log(newFilter);
    return Object.assign({}, state, { [key]: newFilter });
  }
  default:
    return state;
  }
}

console.log возвращает массив с 1 элементом, в котором есть массив с 5 элементами.но я хочу, чтобы 5 ekements были в массиве parrent.и я анализирую URL

  componentDidMount () {
    let {
      location: { search },
      updateFilterState
    } = this.props;

    search = search.slice(1);
    var queries = search.split('&');
    queries.forEach(q => {
      var tmp = q.split('=');
      if (tmp[0] && tmp[1]) {
        if (tmp[0].toLowerCase() === 'triptype') {
          updateFilterState(tmp[0], tmp[1].split(','));
          console.log(tmp[1].split(','));
        } else if (tmp[0].toLowerCase() === 'tripsto') {
          updateFilterState(tmp[0], tmp[1]);
        } else if (tmp[0].toLowerCase() === 'tripsfrom') {
          updateFilterState(tmp[0], tmp[1]);
        } else if (tmp[0].toLowerCase() === 'season') {
          updateFilterState(tmp[0], tmp[1].split(','));
        }
      }
    });
    this.updateQuery(this.props);
  }

Так что все работает, за исключением случаев, когда я хочу обновить.

Довольно новый со всем этим, и застрял почти 3 дня с этим.Надеюсь, вы понимаете, о чем я здесь пытаюсь спросить, так как я довольно новый и не говорящий по-английски, поэтому я не знаю всех терминов, чтобы лучше выразить себя.Кто-нибудь может дать мне несколько советов?

1 Ответ

0 голосов
/ 12 июня 2018

Если я не ошибаюсь, вы снабжаете редуктор массивом для season и tripType.Поэтому, когда вы пытаетесь обновить эти значения, вы фактически не распространяете этот массив.Это ваш value параметр.Следовательно, если вы сделаете это, у вас будет родительский массив с желаемым результатом:

newFilter.push(...value);

... - это синтаксис расширения ES6 .Таким образом, мы распространяем наш массив и помещаем его в наш newFilter.

Но опять же, если я не увижу это неправильно, у вас будут проблемы с этим кодом, поскольку вы не проверяете правильность существования ваших значений.Вы ищете indexOf чего-то, но если вы действительно заполняете свой редуктор массивом, для которого вы ищете этот индекс?

Вот более чистый способ сделать это, если я не ошибаюсь в том, что вы пытаетесьсделайте здесь:

export function filterReducer (state = initialState, action) {
  switch (action.type) {
  case UPDATE_FILTERS: {
    const { key, value } = action.payload;
    if (key === 'tripsFrom' || key === 'tripsTo') {
      return { ...state, [key]: value };
    }  
    const newFilter = Array.isArray(value)
                  ? [ ...new Set( [ ...state[key], ...value ] ) ]
                  : [ ...new Set( [ ...state[key], value ] ) ];
    return { ...state, [key]: newFilter};
  }
  default:
    return state;
  }
}

Некоторые различия с вашим кодом:

  • Я использую синтаксис распространения вместо Object.assign.
  • Вместо проверки всего существованиязначения (перебор массива и выполнение некоторой логики) Я использую здесь Установить объект .Это создает объект уникальных ценностей того, что мы ему даем.Поэтому я обманываю здесь и распространяю наше старое состояние, распространяя наше значение в массив, передавая это нашему множеству, и снова на верхнем уровне распространяя его снова в массив.Если вы не сделаете последний спред, вы получите объект, но здесь нам нужен массив.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...