#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.
Может быть, опробовав это и создав прототип с его помощью, вы в конце концов получите хороший проект стажировки для вас 😉