Как исправить эти ошибки в приложении Redux-React? - PullRequest
1 голос
/ 08 ноября 2019

У меня есть ошибки:enter image description hereRedux Я только начал изучать, пожалуйста, помогите исправить мой код, чтобы мое приложение Redux наконец начало работать, поскольку оно работает на чистом React. Весь проект Здесь я напишу только несколько основных файлов проекта. Здесь я напишу только несколько основных файлов проекта. Здесь я напишу только несколько основных файлов проекта. Здесь я напишу только несколько основных файлов проекта.

Здесь я напишу только несколько основных файлов проекта

App.js (компоненты):


export function searchFilter (search, data) {                                               
  return data.filter(n => n.term.toLowerCase().includes(search));
}

export const days = ["23-08-2019", "24-08-2019", "25-08-2019"];        

class Root extends React.Component {

  componentDidMount() {
    this.props.onFetchData(this.props.day);
  }

  render() {
   const { search, shift, data, filteredData, onFilter, onSetSearch, onFetchData } = this.props;

   return (
      <div>
        <TableSearch value={search}
          onChange={(e) => onSetSearch(e.target.value)} 
          onSearch={() => onFilter()} />

        {days && days.map((day, i) => (
          <button key={day} 
            onClick={() => onFetchData(day)}
            className={i === day ? "active" : ""}>{day}</button>
        ))}
        <br />
        {data && Object.keys(data).map(n => (
          <button data-shift={n}
            onClick={(e) => onFilter({ shift: e.target.dataset.shift })}
            className={n === shift ? "active" : ""}>{n} shift</button>
        ))}

        {data && <TableData data={filteredData} /> }

      </div>
    );
  }
}

export const ConnectedRoot = connect(             
  (state) => state,
  (dispatch) => ({
    onFilter: (args) => dispatch({ type: 'RUN_FILTER', ...args }),
    onSetSearch: (search) => dispatch({ type: 'SET_SEARCH', search }),
    onFetchData: (day) => dispatch(fetchData(day))
  })
)(Root);

Редуктор:

 import { searchFilter } from '../components/app';
 export function reducer (state = {}, action) {

    switch (action.type) {
      case 'SET_SHIFT':
         return Object.assign({}, state, {
            shift: action.shift
         });
      case 'SET_SEARCH':
         return Object.assign({}, state, {
            search: action.search.toLowerCase()
         });
      case 'RUN_FILTER':
         return Object.assign({}, state, {
            shift: action.shift || state.shift,
            search: action.search || state.search,
            filteredData: searchFilter(state.search, state.data[state.shift])
         });
      case 'LOAD_DATA_START':
         return Object.assign({}, state, {
            day: action.day
         });
      case 'LOAD_DATA_END':
         return Object.assign({}, state, {
            data: action.data,
            shift: Object.keys(action.data)[0],
            filteredData: searchFilter(state.search, state.data[state.shift])
         });
      default:
         return state;
   }
}

1 Ответ

1 голос
/ 08 ноября 2019

Проблема в том, что вы ничего не получаете от API (404). См. Изображение ниже.

enter image description here

Это потому, что ваше значение ${day} при загрузке компонента составляет undefined. Таким образом, ваш полный URL-адрес запроса https://api.iev.aero/api/flights/undefined, который ничего не возвращает.

Теперь вы отправляете LOAD_DATA_START, поэтому, когда вы доберетесь до своего редуктора и нажмете на линию case "LOAD_DATA_START, action.day по-прежнему undefined. Так что для action.data вы получаете пустой массив. Это приводит нас к LOAD_DATA_END, где вы устанавливаете значение состояния для shift, равное Object.keys(action.data)[0]. Поскольку action.data пусто, Object.keys(action.data)[0] равно undefined, и ваше приложение не может фильтровать с undefined. Вам нужно иметь значение по умолчанию для this.state.day и использовать его при первоначальной загрузке.

ОБНОВЛЕНИЕ 1

Вам необходимо передать значение по умолчанию в начальной выборке. Попробуйте что-то подобное в вашем componentDidMount:

const days = ["23-08-2019", "24-08-2019", "25-08-2019"];

class Root extends React.Component {
    componentDidMount() {
      this.props.onFetchData(days[this.props.propReducer.day]);
    }
    ...
 }

Нет необходимости экспортировать массив days, просто объявите его как переменную над компонентом.

UPDATE2

Я обновил песочницу с кодом . Несколько вещей были изменены здесь.

Во-первых, ваши действия с избыточностью сохранялись в this.props, но ваше состояние с избыточностью сохранялось в this.props.propReducer, поэтому при рендеринге я изменил переменные, чтобы они указывали на правильное местоположение.

Затем вы отправили SET_SHIFT сразу после LOAD_DATA_END и передали data в качестве полезной нагрузки. Это было значение state.shift, поскольку данные возвращались из начальной выборки. Поэтому, когда вы пытались отфильтровать данные по state.shift в любое другое время, кроме того момента, когда вы впервые сделали выборку в componentDidMount, вы пытались отделить action.data по ключу от всех ранее извлеченных данных. Я удалил это и установил как отдельное действие полностью.

Теперь, чтобы правильно отфильтровать ваши данные, я передал оба извлеченных данных и прошедший день в fetchData как двазначения в полезной нагрузке для LOAD_DATA_END См. ниже.

 dispatch({ type: "LOAD_DATA_END", payload: { data, day } });

И, наконец, у вас редуктор под корпус для "LOAD_DATA_END", я написал ниже.

 var newData = action.payload.data[state.shift].filter(x => {
    return (
      x.actual &&
      x.actual.includes(
        action.payload.day
          .split("-")
          .reverse()
          .join("-")
      )
    );
  });
  return Object.assign({}, state, {
    data: action.payload.data,
    shift: Object.keys(action.payload.data)[0],
    filteredData: searchFilter(state.search, newData)
  });

Что происходитздесь сначала вы отделяете action.payload.data ключом state.shift, который возвращает один массив, либо прибытия, либо отправления. Затем я фильтрую этот массив на основе того, какие рейсы имеют actual (который, как я предполагал, был фактической датой и временем прибытия / отправления), который включает прошедший день. Я должен изменить дату, хотя, потому что в actual время выглядело как 2019-08-24T00:27:49Z, тогда как день выглядел как 24-08-2019. По этой же причине я использовал includes, а не ===, поскольку actual содержит больше информации, чем просто дата, а также время. Теперь ваши данные правильно отфильтрованы и могут быть переданы для окончательной фильтрации, searchFilter, которую я оставлю на ваше усмотрение, чтобы определить, как лучше всего фильтровать на основе ввода пользователя (по времени, номеру рейса, терминалу и т. Д.).

Если вы проверите кодовую ручку, теперь вы сможете фильтровать по смене и по дню.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...