为什么我的减速机不返回状态?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么我的减速机不返回状态?相关的知识,希望对你有一定的参考价值。

我必须在Redux-React上进行申请。使用提取方法,我获取API数据并将其输出到页面(飞机在机场起飞的列表)中。还应该有一个搜索过滤器,用于搜索终端名称。该应用程序还应该具有用于​​昨天,今天和明天的飞机数据的按钮及其子按钮-出发和到达。它应该看起来像这样:

enter image description here

您还可以在纯React的沙箱中查看其工作方式:https://codesandbox.io/s/patient-shape-0fkqk

但是我有任务:API数据必须使用Redux库存储。然后我使用Redux制作了一个应用程序。但是很不幸,我有一些错误,该应用程序无法正常工作。我刚刚开始学习Redux,所以我不明白自己做错了什么以及如何解决。

这是我的代码(下面我写了一个指向沙箱中相同代码的链接):

index.js(action):

export function fetchData (day)                                                    
  return async (dispatch) => 
    dispatch( type: 'LOAD_DATA_START', day );

    const response = await fetch(`https://api.iev.aero/api/flights/$days[this.state.day]`);
    const data = (await response.json()).body;

    dispatch( type: 'LOAD_DATA_END', data );
    dispatch( type: 'SET_SHIFT', data );
  

airplanes.js(reducer):

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

  state =  ...state 

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


index.js(reducer):

import  combineReducers  from 'redux';
import  reducer  from './airplanes';

const rootReducer = combineReducers(
  propReducer: reducer
);

export default rootReducer;

app.js(component):

import React from 'react';
import  Component  from 'react';
import  connect  from 'react-redux'
import  fetchData  from '../actions';
import TableData from "./TableData";
import TableSearch from "./TableSearch";

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



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.map((day, i) => (
          <button key=day 
            onClick=() => onFetchData(day)
            className=i === day ? "active" : "">day</button>
        ))

        <br />

        Object.keys(data).map(n => (
          <button data-shift=n
            onClick=(e) => onFilter( shift: e.target.dataset.shift )
            className=n === shift ? "active" : "">n shift</button>
        ))

        <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))
  )
);

TableData.js(component):

import React from "react";

export default ( data ) => (
  <table className="table">
    <thead>
      <tr>
        <th>ID</th>
        <th>Terminal</th>
        <th>Time</th>
        <th>City</th>
      </tr>
    </thead>
    <tbody>
      data.map(item => (
        <tr key=item.ID>
          <td>item.ID</td>
          <td>item.term</td>
          <td>item.actual</td>
          <td>item["airportToID.city_en"]</td>
        </tr>
      ))
    </tbody>
  </table>
);

TableSearch.js(component):

import React from "react";

export default ( value, onChange, onSearch ) => 
  return (
    <div className="in">
      <div className="inp">
        <button className="btn" onClick=() => onSearch(value)>
          Search
        </button>
      </div>
      <input type="text" className="fo" onChange=onChange value=value />
    </div>
  );
;

index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import  Provider  from 'react-redux';
import  createStore, applyMiddleware  from 'redux';
import App from './components/app';
import reducer from './reducers';
import thunk from 'redux-thunk'
import  ConnectedRoot  from './components/app';

const store = createStore(          
  reducer,
  
    day: 1,
    data: [],
    filteredData: [],
    search: "",
    shift: "departure"
  ,
  applyMiddleware(thunk)
);

ReactDOM.render(
  <Provider store=store>
    <ConnectedRoot />
  </Provider> , document.getElementById('root'));

您还可以在沙盒中看到以下代码:https://codesandbox.io/s/redux-ant-design-filter-table-column-with-slider-s5mzp

答案

您的示例中发生了很多事情,我将其剥离了一些(特别是摆脱了中间件和重击),获得了基本Redux模型的控制权,然后再次构建它。

您的减速器应如下所示:

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

    switch (action.type) 
      case 'SET_SHIFT':
         //no need for break on return
         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])
         );
      //then you definitely need to have this
      default:
         return state;
   


export default reducer;    

我是否可以建议您将一些console.log语句放入化简器中,以便可以看到数据已按预期放入Redux存储中?

另一答案

我看到的主要问题是您没有从减速器返回新状态。

Reducer应该是一个纯函数,给定一个状态和一个动作,将返回一个新状态。

return state放在减速器的底部。

以上是关于为什么我的减速机不返回状态?的主要内容,如果未能解决你的问题,请参考以下文章

修改状态和更新减速器的正确方法? (反应/还原)

反应减速器错误的增量数

Redux state props 值未定义

为啥我的 Redux reducer 认为我的状态是未定义的?

React-Redux - 没有为关键“硬币”提供减速器

我的状态在减速器和消费组件之间变化