2016-11-04 6 views
1

У меня есть приложение для погоды, в котором данные api поступают в разных форматах, поэтому я создал объект методов, которые я могу преобразовать в формат и время от UTC до GMT ,Преобразование данных API в React-Redux: действие или редуцирование

Прямо сейчас у меня есть эти методы, вызываемые данными в моем редукторе.

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

FYI: Я использую axios как мой обещание клиент HTTP на основе и redux-promise-middleware, redux-lodger, & redux-promise как мой промежуточный слой в магазине.

Action Разработчик:

export const fetchCurrentWeather = (city) => { 
const url = `${CURRENT_ROOT_URL}&q=${city},us`; 
const promise = new Promise((resolve, reject) => { 
    axios.get(url) 
    .then(res => resolve(res.data)) 
    .catch(err => reject(err)); 

}); 
return { 
    type: FETCH_CURRENT_WEATHER, 
    payload: promise 
    }; 
}; 

Разбавление:

export default(state = initialState, action) => { 
const data = action.payload; 
switch (action.type) { 
    case `${FETCH_CURRENT_WEATHER}_PENDING`: 
     return {}; 
    case `${FETCH_CURRENT_WEATHER}_FULFILLED`: 
    const prefix = 'wi wi-owm-'; 
    const code = data.weather[0].id; 
    const icon = prefix + code; 
     return { 
      ...state, 
      weatherData: { 
       humidity: data.main.humidity, 
       icon, 
       name: data.name, 
       pressure: unitConverter.toInchesHG(data.main.pressure), 
       sunrise: unitConverter.toGMT(data.sys.sunrise), 
       sunset: unitConverter.toGMT(data.sys.sunset), 
       temp: unitConverter.toFarenheit(data.main.temp), 
       winddir: unitConverter.toCardinal(data.wind.deg), 
       windspd: unitConverter.toMPH(data.wind.speed) 
      }, 
      isFetched: true 
     }; 
    case `${FETCH_CURRENT_WEATHER}_REJECTED`: 
     return { 
      ...state, 
      isFetched: true, 
      err: data 
     }; 
    default: 
     return state; 
    } 
}; 

ответ

2

У вас есть три места, где вы могли бы с пользой обработать ваши исходные данные:

  • render() функция A компонента

    Это обычно не рекомендуется, так как это будет означать, что данные обрабатываются каждый раз, когда компонент визуализируется. Если вы используете пакет, такой как reselect, вы можете уменьшить проблемы с производительностью с помощью кеширования, но даже тогда фактический код, например. сортировка или фильтрация следует хранить в mapStateToProps().

  • В редукторе

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

  • Действие санк

    На мой взгляд, действие преобразователь правильное место для разовых преобразований данных, таких как нормализация/преобразования импортируемых необработанных данных. Это не просто типичная подзадача действия (например, получение данных о погоде -> конвертация цели по Фаренгейту), но также имеет дополнительное преимущество - не хранить бесполезные данные, даже если временно, в состоянии.

    Цитирую Дэн Абрамов:

    ... объекты действия [являются] минимальные представления того, что произошло и государственных объектов [являются] минимальные представления того, что необходимо для рендеринга прямо сейчас.

Конечная нота - селекторы

Хотя я уже говорил выше, что компонент не является хорошим местом для выполнения преобразований сырым-данных, на самом деле я думаю, что есть аргумент, который будет сделан для сохраняя исходные данные в состоянии redux и используя пакет, такой как reselect, чтобы представить нормированные или вычисленные значения через selectors по мере необходимости.

Одним из способов достижения этой цели было бы иметь функцию selector, которая выполняет нормализацию данных на определенной части необработанных данных. Используя пакет reselect, это преобразование будет кэшироваться и поэтому выполняется только один раз. Это имело бы преимущество ленивое преобразование данных только по мере необходимости.

+0

спасибо! Я играл с идеей перемещения конверсий к действию, потому что казалось, что я все еще выполняю и «действие» на данных, а редуктор на самом деле не полагается делать это. Я проверю пакет 'reselect'. Еще раз спасибо! – rockchalkwushock