首页 > 解决方案 > 在 App 中使用 Redux-Sauce 时遇到问题?我究竟做错了什么?

问题描述

我应该从端点获取数据并使用 Redux-Sauce 显示结果。一切都很好,只是我在获取数据后似乎无法更新状态。阅读文档,这就是我能想到的。请告诉我我做错了什么!?如何更新调用 HomeContainer.js 中的动作创建者的状态?

链接到代码沙盒

https://codesandbox.io/s/fragrant-sky-56yhi?file=/src/index.js

HomeContainer.js

import React, { useEffect, useState } from "react";
import axios from "axios";
import { connect } from "react-redux";
import Creators from "../redux/Reducers/reducers";

const HomeContainer = ({ iTunesData, actions }) => {
  const { loading, data, error } = iTunesData;
  const [searchTerm, setSearchTerm] = useState("");

  const submitHandler = (e) => {
    e.preventDefault();

    const getData = async () => {
      actions.fetchDataRequest();

      try {
        const { data } = await axios.get(
          `https://itunes.apple.com/search?term=${searchTerm}`
        );

        // console.log(data);

        actions.fetchDataSuccess(data);
      } catch (error) {
        actions.fetchDataFail(error);
      }
    };

    getData();
    // console.log("On submit handler clicked!");
  };

  // console.log(iTunesData, actions);
  // console.log(searchTerm);
  // console.log(iTunesData);
  console.log(loading, data, error);
  return (
    <form onSubmit={submitHandler}>
      <h1> Home Container</h1>

      <input
        placeholder="Search..."
        type="text"
        onChange={(e) => setSearchTerm(e.target.value)}
      />
      <button>Go</button>
    </form>
  );
};

const mapStateToProps = (state, ownProps) => {
  return {
    iTunesData: state
  };
};
const mapDispatchToProps = (state, ownProps) => {
  return {
    actions: Creators
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(HomeContainer);

减速器.js

import { createReducer, createActions } from "reduxsauce";

const { Types, Creators } = createActions({
  fetchDataRequest: null,
  fetchDataSuccess: ["payload"],
  fetchDataFail: ["error"]
});

export default Creators;

const initialState = {
  loading: false,
  data: [],
  error: false
};

export const fetchDataRequest = (state = initialState, action) => {
  return { ...state, loading: true, data: [], error: false };
};

export const fetchDataSuccess = (state = initialState, action) => {
  return { ...state, data: action.payload, error: false };
};

export const fetchDataFail = (state = initialState, action) => {
  return { ...state, data: null, error: action.error };
};

// map our action types to our reducer functions
export const HANDLERS = {
  [Types.FETCH_DATA_REQUEST]: fetchDataRequest,
  [Types.FETCH_DATA_SUCCESS]: fetchDataSuccess,
  [Types.FETCH_DATA_FAIL]: fetchDataFail
};

export const reducer = createReducer(initialState, HANDLERS);

store.js

import { applyMiddleware, combineReducers, compose, createStore } from "redux";
import { reducer } from "./Reducers/reducers";
import thunk from "redux-thunk";

const store = createStore(reducer, applyMiddleware(thunk));

export default store;

index.js

import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import store from "./redux/store";

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </StrictMode>,
  rootElement
);

标签: reactjsredux

解决方案


mapDispatchToProps错了。写得就像你想使用它一样,它需要真正绑定dispatch到你不需要的动作。

如果要使用该嵌套,则必须bindActionCreators手动调用。

const mapDispatchToProps = (dispatch) => {
  return {
    actions: bindActionCreators(Creators, dispatch)
  };
};

否则你也可以使用“对象表示法”

const mapDispatchToProps = Creators

在这种情况下,绑定的动作创建者将可用props.fetchDataSuccess,而不是props.actions.fetchDataSuccess

一般来说,也建议不要使用connect函数组件,而是使用 React-Redux 钩子useSelectoruseDispatch.

https://react-redux.js.org/api/hooks

另外,至于你的实习,请将官方的 Redux 风格指南转发给你的团队,Redux 维护者致以最诚挚的问候;) https://redux.js.org/style-guide/style-guide/
我们真的希望他们使用官方的 Redux 工具包,因为它比 Redux-Sauce 已经做的更简化了他们的代码 - 包括由于immer集成和包含完整的 api 缓存抽象而允许 reducer 中的不可变逻辑。

也许尝试一下并使用它进行原型设计最终可能会为您提供一个不错的实习项目;)


推荐阅读