Проблемы с использованием Redux-соуса в приложении? Что я делаю не так?

#reactjs #redux

Вопрос:

Предполагается, что я должен извлекать данные из конечной точки и отображать результаты с помощью Redux-Sauce. Все в порядке, за исключением того, что я, похоже, не могу обновить состояние после получения данных. Прочитайте документы, так что это то, что я мог бы придумать. Пожалуйста, скажите мне, что я делаю не так!? Как мне обновить состояние, вызывая создателей действий внутри HomeContainer.js?

Ссылка на CodeSandbox

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

 

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

 

Комментарии:

1. Хотя это не отвечает на ваш вопрос, пожалуйста, обратите внимание, что если вы только изучаете Redux, все, что делает Redux-Sauce (и многое другое), уже является частью официального инструментария Redux, именно так мы официально рекомендуем писать любой код Redux в настоящее время (на данный момент 2 года). Пожалуйста, ознакомьтесь с официальным руководством по Redux для этого: redux.js.org/tutorials/essentials/part-1-overview-concepts

2. на самом деле, это для стажировки, и они хотят, чтобы я включил redux-соус в приложение 🙁

Ответ №1:

Ты mapDispatchToProps ошибаешься. Написанный так, как вы хотите его использовать, он должен быть четко привязан dispatch к действиям, которые вы не делаете.

Если вы хотите использовать эту вложенность, вам придется позвонить bindActionCreators вручную.

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

В противном случае вы также можете использовать «обозначение объекта»

 const mapDispatchToProps = Creators
 

в этом случае создатели связанных действий будут доступны как props.fetchDataSuccess , нет props.actions.fetchDataSuccess .

Как правило, также рекомендуется connect вообще не использовать с функциональными компонентами, но крючки React-Redux useSelector и useDispatch .

Видишь https://react-redux.js.org/api/hooks

Кроме того, что касается вашей стажировки, пожалуйста, направьте официальное руководство по стилю Redux вашей команде с наилучшими пожеланиями от сопровождающего Redux 😉 https://redux.js.org/style-guide/style-guide/
Мы действительно хотим, чтобы они использовали официальный инструментарий Redux, поскольку он упростит их код намного больше, чем уже делает Redux-Sauce, в том числе позволяет использовать неизменяемую логику в редукторах благодаря immer интеграции и содержит полномасштабную абстракцию кэша api.

Может быть, опробовав это и создав прототип с его помощью, вы в конце концов получите хороший проект стажировки для вас 😉