如何将react-hooks,redux和打字稿结合在一起?

时间:2019-08-12 15:24:03

标签: reactjs typescript redux react-redux react-hooks

我一直在尝试结合React-hooks,Redux和Typescript。每当我纠正错误时,都会出现一个新错误。

任何人都可以看到问题所在吗?

现在我收到关于减速机的以下错误

  

未处理的拒绝(TypeError):action.places不可迭代

没有打字稿,此代码有效。所以我应该在打字方面有所遗漏或做错什么。

// Types

export interface Place {
  type: string;
  geometry: Geometry;
  properties: Properties;
  id: number;
}

interface Geometry {
  type: string;
  coordinates: [number, number];
}

interface Properties {
  Id: string;
  Title: string;
  Url: string;
  ImageUrl: string;
  Bullets: boolean;
}


export const FETCH_DATA: string = "FETCH_DATA";

export interface FetchDataAction {
  type: typeof FETCH_DATA;
  places: Place[];
}

export type PlaceActionTypes = FetchDataAction;

export type AppActions = PlaceActionTypes;

// Action
// places = axios.create({baseURL}) (the API is an array of type Place[])

export const fetchPlaces = () => async (dispatch: Dispatch) => {
  const response = await places.get(`places`);

  dispatch({
    type: "FETCH_DATA",
    payload: response.data
  });
};

// Reducer

export const initialState: Place[] = [];

const placeReducer = (state = initialState, action: PlaceActionTypes) => {
  switch (action.type) {
    case FETCH_DATA:
      return [...state, ...action.places];

    default:
      return state;
  }
};



// Here is my Component

const HomePage = () => {
  const places: Place[] = useSelector((state: any) => state.places);
  const dispatch = useDispatch();

  useEffect(() => {
    places.length === 0 && dispatch(fetchPlaces());
  });

  console.log(places);

  return <div>HomePage</div>;
};

1 个答案:

答案 0 :(得分:3)

使用传播运算符时出错。

在代码中,您尝试使用用于可迭代对象的语法来扩展对象。对象散布的正确语法是const cloneObject = {...originalObject};,它实际上是在原始对象的键上进行迭代,并将原始的键/值对复制到新的对象常量中。

From MDN

对于函数调用:myFunction(...iterableObject);

对于数组文字或字符串:[...iterableObject, 'one', '2', 'three'];

对于对象文字(ECMAScript 2018中的新增功能):let objectClone = { ...object };

因此在reducer中,返回值应该是一个对象。如果需要数组,则可以在创建对象后创建它

const placeReducer = (state = initialState, action: PlaceActionTypes) => {
  switch (action.type) {
    case FETCH_DATA:
      return {...state, ...action.places};

    default:
      return state;
  }
};