Redux createStore()已被弃用 - 在Redux action中无法从getState()获取状态

55

所以,Redux中的createStore()已经被弃用了,建议使用@reduxjs/toolkit中的configureStore()

我很确定这与我无法在我的action中使用getState()来获取userInfo状态有关。

userLogingetState()返回undefined。但是当我删除getState()时,该action可以工作。

STORE:

import { configureStore } from '@reduxjs/toolkit'
import thunk from 'redux-thunk'
import {
  productAddReducer,
  productDeleteReducer,
  productDetailsReducer,
  productListReducer,
  productUpdateReducer,
} from './reducers/productReducers'
import { composeWithDevTools } from 'redux-devtools-extension'
import {
  userLoginReducer,
  userRegisterReducer,
  userDetailsReducer,
  userListReducer,
  userDeleteReducer,
  userUpdateReducer,
} from './reducers/userReducers'

const reducer = {
  // User
  userLogin: userLoginReducer,
  userRegister: userRegisterReducer,
  userDetails: userDetailsReducer,
  userList: userListReducer,
  userDelete: userDeleteReducer,
  userUpdate: userUpdateReducer,
  // Product
  productAdd: productAddReducer,
  productList: productListReducer,
  productDetails: productDetailsReducer,
  productUpdate: productUpdateReducer,
  productDelete: productDeleteReducer,
}

const userInfoFromStorage = localStorage.getItem('userInfo')
  ? JSON.parse(localStorage.getItem('userInfo'))
  : null

const preLoadedState = {
  userLogin: { userInfo: userInfoFromStorage },
}

const middleware = [thunk]

const store = configureStore({
  reducer,
  preLoadedState,
  middleware,
})

export default store

操作:

import axios from 'axios'
import {
  PRODUCT_ADD_FAIL,
  PRODUCT_ADD_REQUEST,
  PRODUCT_ADD_SUCCESS,
  PRODUCT_DELETE_FAIL,
  PRODUCT_DELETE_REQUEST,
  PRODUCT_DELETE_SUCCESS,
  PRODUCT_DETAILS_FAIL,
  PRODUCT_DETAILS_REQUEST,
  PRODUCT_DETAILS_SUCCESS,
  PRODUCT_LIST_FAIL,
  PRODUCT_LIST_REQUEST,
  PRODUCT_LIST_SUCCESS,
  PRODUCT_UPDATE_FAIL,
  PRODUCT_UPDATE_REQUEST,
  PRODUCT_UPDATE_SUCCESS,
} from '../constants/productConstants'

export const addProduct = product => async (dispatch, getState) => {
  try {
    dispatch({ type: PRODUCT_ADD_REQUEST })

    const {
      userLogin: { userInfo },
    } = getState()

// USER INFO IS 'UNDEFINED' - ERROR: CANNOT READ PROPERTY OF DATA
// ACTION WORKS WHEN REMOVING USERINFO FROM THE ACTION

    const config = {
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${userInfo.token}`,
      },
    }

    const { data } = await axios.post('/product', product, config)

    dispatch({
      type: PRODUCT_ADD_SUCCESS,
      payload: data,
    })
  } catch (error) {
    dispatch({
      type: PRODUCT_ADD_FAIL,
      payload:
        error.message && error.response.data.message
          ? error.response.data.message
          : error.message,
    })
  }
}

export const listProducts = () => async dispatch => {
  try {
    dispatch({ type: PRODUCT_LIST_REQUEST })

    const { data } = await axios.get('/product')

    dispatch({
      type: PRODUCT_LIST_SUCCESS,
      payload: data,
    })
  } catch (error) {
    dispatch({
      type: PRODUCT_LIST_FAIL,
      payload:
        error.message && error.response.data.message
          ? error.response.data.message
          : error.message,
    })
  }
}

export const listProductDetails = id => async dispatch => {
  try {
    dispatch({ type: PRODUCT_DETAILS_REQUEST })

    const { data } = await axios.get(`/product/${id}`)

    dispatch({
      type: PRODUCT_DETAILS_SUCCESS,
      payload: data,
    })
  } catch (error) {
    dispatch({
      type: PRODUCT_DETAILS_FAIL,
      payload:
        error.message && error.response.data.message
          ? error.response.data.message
          : error.message,
    })
  }
}

export const updateProduct = product => async (dispatch, getState) => {
  try {
    dispatch({ type: PRODUCT_UPDATE_REQUEST })

    const {
      userLogin: { userInfo },
    } = getState()

    const config = {
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${userInfo.token}`,
      },
    }

    const { data } = await axios.put(`/product/${product._id}`, product, config)

    dispatch({
      type: PRODUCT_UPDATE_SUCCESS,
      payload: data,
    })
  } catch (error) {
    dispatch({
      type: PRODUCT_UPDATE_FAIL,
      payload:
        error.message && error.response.data.message
          ? error.response.data.message
          : error.message,
    })
  }
}

export const deleteProduct = id => async (dispatch, getState) => {
  try {
    dispatch({ type: PRODUCT_DELETE_REQUEST })

    const {
      userLogin: { userInfo },
    } = getState()

    const config = {
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${userInfo.token}`,
      },
    }

    const { data } = await axios.delete(`/product/${id}`, config)

    dispatch({
      type: PRODUCT_DELETE_SUCCESS,
      payload: data,
    })
  } catch (error) {
    dispatch({
      type: PRODUCT_DELETE_FAIL,
      payload:
        error.message && error.response.data.message
          ? error.response.data.message
          : error.message,
    })
  }
}

7
这篇文章似乎没有提出问题。 - TylerH
@TylerH 这篇帖子被用作审核(我没过),但我同意你的观点。这不是一个好问题或真实的问题。 - user17242583
7个回答

184

我是Redux的维护者,也是添加了“createStore已弃用”信息的人 :)

请注意,这与您的实际应用程序代码无关。它确实是特别针对像您这样使用“纯Redux”的用户的信息——它试图告诉您,您正在遵循更难使用的模式,而我们希望您改用Redux Toolkit,因为它会让您的生活更轻松:)

请注意,这甚至不是在控制台中打印的运行时警告——它只是编辑器中的一个视觉指示,就像createStore

有关我们为什么希望人们使用Redux Toolkit编写Redux代码以及如何这样做的更多详细信息,请参阅这些Redux文档页面:


30
请注意,我的翻译只涉及以下内容:请不要将弃用消息用作垃圾邮件。我知道你认为reduxtoolkit更好,但那是你的观点。我喜欢createSlice模式中的很多东西,我不介意它成为redux的一部分或者独立存在,但我不想使用它所附带的许多内容,我也绝对不希望我的可变代码被神奇地转换为不可变操作。 - Pablo Barría Urenda
6
@Guy:从“营销”的角度来看,“我们希望人们阅读这篇文章并了解RTK”,当然可以这么理解。但实际上,“弃用”(deprecation)本身就是这个意思:让那些“制作”工具的人告诉那些“使用”工具的人“不要再以这种方式使用它,因为它已经不应该再这样使用了”。这对于每个框架和每种编程语言都是如此。例如,Java 多年前就有类似的@deprecated属性:https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html 。这其实就是它存在的全部意义 :) - markerikson
5
@Guy: 我们也希望现有的Redux开发人员使用RTK,因为我们希望每个Redux开发者都能使用RTK。但是,确实有一小部分用户只想使用Redux核心本身,并且因为各种原因不喜欢RTK,这就是为什么这是一个“弃用”,而不是一个真正删除createStore的主要版本 - 我们不会破坏现有的代码。但作为维护者,我们的工作是指导人们采用我们认为最适合使用Redux的方法,即RTK。 - markerikson
3
我也想表达我对这种废止折旧信息的不满。 - bouffelec
4
@bouffelec:请阅读链接文章。这不是“弃用消息的废弃”,而是有意向我们的用户发出通知,告知有更好的编写Redux代码的方式,就像其他标记某些API为弃用的库一样。 - markerikson
显示剩余52条评论

45

你也可以像这样使用import:

import { legacy_createStore as createStore } from 'redux';

2
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

8

我也遇到了同样的警告,然后我按照VS Code提示的做法去做了。我导入了legacy_createStore。

import {legacy_createStore} from 'redux'

或者您可以使用别名,以便您的代码保持不变。

import {legacy_createStore as createStore} from 'redux'

1
  • createStore 已经被弃用了,你正在使用基础的 Redux 创建 store 的方法。这种模式比较难用。因此 Redux 的创建者推荐我们使用 Redux Toolkit。你可以非常容易地使用 Redux Toolkit 创建 store。在 Redux Toolkit 中,你可以使用 configureStore 方法,它将自动处理 store 的设置并包装 createStore API。

  • 在大多数情况下,你应该使用 @reduxjs/toolkit 包中的 configureStore 方法,而不是直接调用 createStore 方法。由于 configureStore 内部调用 createStore,因此它不会消失,代码将继续工作。但如果你正在开始一个新项目,请注意,我们建议从2019年起,对于任何新编写的Redux代码,使用官方的Redux Toolkit。

    更多详情请看 ===> https://redux.js.org/tutorials/fundamentals/part-8-modern-redux


0
作为一个React模块
import redux from 'redux';
import { legacy_createStore as createStore } from 'redux';

作为一个Node模块
const redux = require("redux");
const createStore = redux.legacy_createStore;

0

使用 redux:

如果你想使用 createStore 而不出现这个视觉上的弃用警告,请使用 legacy_createStore 导入代替:

import { legacy_createStore as createStore } from "redux";

使用 redux-toolkit:

Redux Toolkit 是我们今天编写 Redux 逻辑的推荐方法,包括存储设置、reducers、数据获取等。

Redux Toolkit 具有 configureStore API,它是 createStore 的改进版本,简化了(store)设置并帮助避免常见的错误。 configureStore 包装了 Redux 核心的 createStore API,并自动处理大部分存储设置。

import { configureStore } from "@reduxjs/toolkit";

https://redux.js.org/tutorials/fundamentals/part-8-modern-redux#using-configurestore


0

大家好,我现在是在2023年,根据 Redux 的版本 4.0.0 及以上,使用 Redux Toolkit 中的 configureStore 方法被推荐作为创建 Redux 存储的方式。Redux Toolkit 的 configureStore 方法包装了原始的 createStore 方法,并自动处理了大部分存储设置,因此初始安装 reduxjs/toolkit。

npm install @reduxjs/toolkit

如果你是一个喜欢纺纱的人
yarn add @reduxjs/toolkit

然后放在它应该放的地方。
import { configureStore } from '@reduxjs/toolkit';

这个简单的导入明确地应用了中间件,例如applyMiddleware、Redux Thunk和其他中间件。在我看来,少一些样板代码,只追求简洁,谁不想要呢。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接