当前位置: 首页 > 面试题库 >

React Redux从后端方法获取数据

薄兴昌
2023-03-14
问题内容

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

到目前为止,我所看到的方法是,在组件加载之前获取数据,并使用响应中的数据调度操作。但是我最近开始对此进行深入研究,并且看到了我较早知道的React-
Thunk库,并开始怀疑从后端/ API获取数据的最佳实践是什么?React Hooks对此主题有任何更改吗?重要的是要知道这一点吗?

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


问题答案:

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

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

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

通过创建名称的目录 终极版 或像你的任何名称 src文件夹
,然后创建两个文件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
...

store.js

在此文件中,我们进行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));

rootReducer.js

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

// redux/rootReducer.js
import { combineReducers } from "redux";

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

const rootReducer = combineReducers({
  shop: productReducer,
});

export default rootReducer;

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

export const ShopActionTypes = {
  FETCH_PRODUCTS_START: "FETCH_PRODUCTS_START",
  FETCH_PRODUCTS_SUCCESS: "FETCH_PRODUCTS_SUCCESS",
  FETCH_PRODUCTS_FAILURE: "FETCH_PRODUCTS_FAILURE"
};

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

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

product.reducer.js 在此文件中,我们创建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;

product.selector.js 在这个文件中,我们选择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
);

Index.js 在此文件中包装了整个应用程序和组件,并带有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")
);

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

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

或具有功能组件(useEffect钩子)的App.js 在此文件中,我们确实连接到具有功能组件的商店和状态

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


 类似资料:
  • 错误:网络错误在createError(createError.js:16)在XMLHttpRequest.handle错误(xhr.js:84) 当我试图从我创建的后端获取数据时,我遇到了上述错误。 我已在我的操作中编写了以下代码, 我能够在Postman中从该API获取数据。 邮递员回应:- 操作类型文件:- export const GET_PEOPLE='GET_PEOPLE'

  • 我在我的项目中使用Spring Data JPA和Hibernate JPA提供程序。在我的服务中,我有一个方法,它将一个实体保存在数据库中,而不是使用返回的对象,我试图获取关于该实体的更多细节。因此,无法获取详细信息。在日志中,我只看到insert语句,而没有select详细信息。 下面是我的代码: 更新:我从服务和测试中删除了@Transactional annotaion。现在,当我保存一个

  • 我一直在尝试使用nativescript创建一个android应用程序。我正在使用fetch模块从服务器获取响应。当我试图从httpbin获得响应时。org/get,没关系。但当我试图从本地服务器获取响应时,网络请求失败。错误 发送到httpbin。组织/获取- 发送到本地主机:8000/api- 当我尝试从纯节点中的localhost:8000/api获取响应时。js通过请求模块。它工作得很好。

  • 我无法从API获取数据。我尝试了不同的方法,但没有成功。这是我的代码和API。我想通过react-fetch方法使用这些数据(JSON)。 当我使用这个获取api时,它正在工作。数据与上面的数据几乎相同,但那不是真正的Rest API。

  • 从API获取信息后,我正在方法中设置对象的值。尽管变量team已声明为静态并初始化,并且我在设置数据时使用了运算符,但在对象中没有设置数据,当我执行team.getTeamName()时,我会得到 代码:

  • 这是我收到的错误: 请求的资源上不存在“< code > Access-Control-Allow-Origin ”标头。因此,不允许访问源“https://s.codepen.io”。如果不透明响应满足您的需要,请将请求的模式设置为' < code>no-cors ',以便在禁用cors的情况下获取资源。 我将模式设置为但仍然没有运气。