React Redux从后端方法获取数据

我有些困惑,很想得到一个答案,可以帮助我理清思路。假设我有一个后端(nodejs,express等),我在其中存储用户及其数据,有时我想从后端获取数据,例如用户登录后的用户信息或产品列表并保存他们在状态。

到目前为止,我所看到的方法是,在组件加载之前获取数据,并使用响应中的数据调度操作。但是我最近开始对此进行深入研究,并且看到了我较早知道的React-

Thunk库,并开始怀疑从后端/ API获取数据的最佳实践是什么?React Hooks对此主题有任何更改吗?重要的是要知道这一点吗?

我有点傻,但找不到与该主题完全相关的文章或视频:)

回答:

若要执行此最佳做法,请使用以下方法:

我使用了一些软件包和模式来进行最佳实践:

  • redux-logger,用于在浏览器控制台中记录日志操作和状态。
  • 重新选择选择器可以计算派生数据,从而允许Redux存储最小可能状态等。
  • redux-thunk Thunks是基本Redux副作用逻辑的推荐中间件,其中包括需要访问存储的复杂同步逻辑以及简单的异步逻辑(例如AJAX请求等)。
  • 适用于api的axios(用于浏览器和node.js的基于Promise的HTTP客户端)

通过创建名称的目录 或像你的任何名称

,然后创建两个文件store.js,并rootReducer.js在终极版目录。我们假设从API获取产品。

通过创建名称的新目录 在终极版目录中,然后通过名称创建四个文件product.types.js,

product.actions.js, product.reducer.js,

product.selector.jsredux/product目录

...

src

App.js

redux

product

product.types.js

product.actions.js

product.reducer.js

rootReducer.js

store.js

Index.js

package.json

...

在此文件中,我们进行redux配置

// redux/store.js:

import { createStore, applyMiddleware } from "redux";

import logger from "redux-logger";

import thunk from "redux-thunk";

import rootReducer from "./root-reducer";

const middlewares = [logger, thunk];

export const store = createStore(rootReducer, applyMiddleware(...middlewares));

combineReducers辅助函数将值不同的归约函数的对象转换为可以传递给的单个归约函数createStore

// redux/rootReducer.js

import { combineReducers } from "redux";

import productReducer from "./product/product.reducer";

const rootReducer = combineReducers({

shop: productReducer,

});

export default rootReducer;

在此文件中,我们定义用于管理动作类型的常量。

export const ShopActionTypes = {

FETCH_PRODUCTS_START: "FETCH_PRODUCTS_START",

FETCH_PRODUCTS_SUCCESS: "FETCH_PRODUCTS_SUCCESS",

FETCH_PRODUCTS_FAILURE: "FETCH_PRODUCTS_FAILURE"

};

在此文件中,我们创建处理动作的动作创建者。

// redux/product/product.actions.js

import { ShopActionTypes } from "./product.types";

import axios from "axios";

export const fetchProductsStart = () => ({

type: ShopActionTypes.FETCH_PRODUCTS_START

});

export const fetchProductsSuccess = products => ({

type: ShopActionTypes.FETCH_PRODUCTS_SUCCESS,

payload: products

});

export const fetchProductsFailure = error => ({

type: ShopActionTypes.FETCH_PRODUCTS_FAILURE,

payload: error

});

export const fetchProductsStartAsync = () => {

return dispatch => {

dispatch(fetchProductsStart());

axios

.get(url)

.then(response => dispatch(fetchProductsSuccess(response.data.data)))

.catch(error => dispatch(fetchProductsFailure(error)));

};

};

在此文件中,我们创建productReducer用于处理动作的函数。

import { ShopActionTypes } from "./product.types";

const INITIAL_STATE = {

products: [],

isFetching: false,

errorMessage: undefined,

};

const productReducer = (state = INITIAL_STATE, action) => {

switch (action.type) {

case ShopActionTypes.FETCH_PRODUCTS_START:

return {

...state,

isFetching: true

};

case ShopActionTypes.FETCH_PRODUCTS_SUCCESS:

return {

...state,

products: action.payload,

isFetching: false

};

case ShopActionTypes.FETCH_PRODUCTS_FAILURE:

return {

...state,

isFetching: false,

errorMessage: action.payload

};

default:

return state;

}

};

export default productReducer;

在这个文件中,我们选择productsisFetching从商店状态。

import { createSelector } from "reselect";

const selectShop = state => state.shop;

export const selectProducts = createSelector(

[selectShop],

shop => shop.products

);

export const selectIsProductsFetching = createSelector(

[selectShop],

shop => shop.isFetching

);

在此文件中包装了整个应用程序和组件,并带有Provider用于访问商店和州的子组件。

// src/Index.js

import React from "react";

import ReactDOM from "react-dom";

import App from "./App";

import { Provider } from "react-redux";

import { store } from "./redux/store";

ReactDOM.render(

<Provider store={store}>

<App />

</Provider>,

document.getElementById("root")

);

在此文件中,我们确实连接到商店并使用类组件声明状态

// src/App.js

import React, { Component } from "react";

import { connect } from "react-redux";

import { createStructuredSelector } from "reselect";

import {

selectIsProductsFetching,

selectProducts

} from "./redux/product/product.selectors";

import { fetchProductsStartAsync } from "./redux/product/product.actions";

class App extends Component {

componentDidMount() {

const { fetchProductsStartAsync } = this.props;

fetchProductsStartAsync();

}

render() {

const { products, isProductsFetching } = this.props;

console.log('products', products);

console.log('isProductsFetching', isProductsFetching);

return (

<div className="App">Please see console in browser</div>

);

}

}

const mapStateToProps = createStructuredSelector({

products: selectProducts,

isProductsFetching: selectIsProductsFetching,

});

const mapDispatchToProps = dispatch => ({

fetchProductsStartAsync: () => dispatch(fetchProductsStartAsync())

});

export default connect(

mapStateToProps,

mapDispatchToProps

)(App);

在此文件中,我们确实连接到具有功能组件的商店和状态

// src/App.js

import React, { Component, useEffect } from "react";

import { connect } from "react-redux";

import { createStructuredSelector } from "reselect";

import {

selectIsProductsFetching,

selectProducts

} from "./redux/product/product.selectors";

import { fetchProductsStartAsync } from "./redux/product/product.actions";

const App = ({ fetchProductsStartAsync, products, isProductsFetching}) => {

useEffect(() => {

fetchProductsStartAsync();

},[]);

console.log('products', products);

console.log('isProductsFetching', isProductsFetching);

return (

<div className="App">Please see console in browser</div>

);

}

const mapStateToProps = createStructuredSelector({

products: selectProducts,

isProductsFetching: selectIsProductsFetching,

});

const mapDispatchToProps = dispatch => ({

fetchProductsStartAsync: () => dispatch(fetchProductsStartAsync())

});

export default connect(

mapStateToProps,

mapDispatchToProps

)(App);

以上是 React Redux从后端方法获取数据 的全部内容, 来源链接: utcz.com/qa/429378.html

回到顶部