53

So, the createStore() Redux is now deprecated and configureStore() is recommended from @reduxjs/toolkit.

I'm pretty sure it's related to not being able to get userInfo state using getState() in my actions.

getState() of userLogin returns undefined. But when I remove getState(), the action works.

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

ACTION:

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,
    })
  }
}
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Evan B
  • 567
  • 1
  • 4
  • 6
  • 7
    This post does not seem to ask a question. – TylerH May 04 '22 at 21:22
  • @TylerH this post was used as an audit (which I failed), but I agree with you. It's not a good question or a real one. –  May 05 '22 at 16:03

5 Answers5

167

I'm a Redux maintainer, and the person who added that "createStore is deprecated" message :)

For the record this has nothing to do with your actual application code. It is specifically a message to users like you who are using "plain Redux" - it's trying to tell you that you're following patterns that are much harder to use, and we want you to use Redux Toolkit instead because it will make your life much easier :)

You'll note that this isn't even a runtime warning being printed in the console - it's literally just a visual indicator in your editor, like createStore.

Please see these Redux docs pages for more details on why we want people using Redux Toolkit to write Redux code, and how to do so:

markerikson
  • 63,178
  • 10
  • 141
  • 157
  • Thank you for your response, Mark and Emile. I created a test app for the purpose of learning Redux toolkit. I started by making the counter. Then I connected a backend and db and I am making axios requests from the reducer. I've been successful to a degree and wondering if you can provide any docs or videos on more advanced redux toolkit functionality such as sending requests to the backend etc? – Evan B Apr 22 '22 at 14:15
  • 1
    Yes, the "Essentials" tutorial I linked in my answer specifically goes over all of the features in Redux Toolkit, including how to handle data fetching. Also, note that in Redux, a reducer may _never_ make async requests of any kind! That needs to be _outside_ the reducer - usually in a "thunk" function. – markerikson Apr 23 '22 at 16:14
  • @markerikson if I understand your comment correctly the idea behind the deprecation of createStore is only to inform « plain redux » users that RTK exist, meaning you will not delete createStore in a future major version? – Patrick Lafrance Apr 26 '22 at 12:17
  • 1
    Correct. **We are _not_ going to break actual working code**. Even though the rules of semver would give us license to actually make real breaking changes in a major version, we are _not_ going to remove the `createStore` API. However, per the linked post, **we _want_ everyone to stop using `createStore`, and switch to using `configureStore` (and the rest of Redux Toolkit) instead**. Thus the attempt to nudge people and let them know that RTK exists. – markerikson Apr 27 '22 at 17:55
  • @markerikson with RTK, do we still need to use `redux-thunk`, and import `applyMiddleware` from `redux`? – Ben Li May 05 '22 at 00:42
  • 28
    @markerikson Please, please, please, don't use deprecation messages as SPAM. I understand you think reduxtoolkit is better, but that is *your* opinion. There's a lot I like about the createSlice pattern, and I wouldn't mind that being part of redux or existing on its own, but I do not want many of the stuff it comes with, and I definitely not want my mutable code magically transformed into immutable operations. – Pablo Barría Urenda May 05 '22 at 20:31
  • 6
    @Guy : it's "marketing" in the sense that "we want people to read this and learn about RTK", sure. But that's literally the point of "deprecation" in the first place: the people who _make_ a tool telling the people that _use_ the tool "stop using it this way, that's not how it should be used anymore". This has been true for every framework and every language. For example, Java has had a similar `@deprecated` attribute for years: https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html . That's literally the whole point of it in the first place :) – markerikson May 08 '22 at 22:01
  • 5
    @Guy : We _also_ want _existing_ Redux devs to use RTK, because we want _every_ Redux dev to use RTK. But yes, there is a small but somewhat vocal minority of users who _only_ want to use the Redux core by itself, and don't like RTK for various reasons. That's why this is a "deprecation", and not a major version that actually removes `createStore` - we're not going to break working code. But as maintainers, it's our job to point people to the approach we feel works best for using Redux, and that's RTK. – markerikson May 14 '22 at 00:49
  • 3
    I also would like to express my discontent about this disuse of a depreciation message. – bouffelec Jun 07 '22 at 09:39
  • 4
    @bouffelec : Please read the [linked article](https://redux.js.org/introduction/why-rtk-is-redux-today). This is not a "disuse of a deprecation message". This is an intentional notification to our users that there is a better way to write Redux code, same as any other library that marks some API as deprecated. – markerikson Jun 08 '22 at 15:03
  • 1
    this message really a mistake, it make programmers get confused. hope you revise yourself. – Astro Jun 24 '22 at 12:53
  • @markerikson we use redux for managing a few middlewares with our routing library (`found`) and do not use any redux APIs directly. It doesn't make sense for us to add a new dependency and extra bytes to avoid this warning. I am happy to ignore the warning but this really shouldn't be removed. It needs to be possible to use base redux without deps. – monastic-panic Aug 10 '22 at 14:57
  • @monastic-panic: _please_ read the linked articles and release notes - **we are _not_ going to actually _remove_ `createStore`!** and there is no _runtime_ warning - just a visual strikethrough in your editor when you import. However, yes, we _want_ everyone to be using RTK, or at the very worst, acknowledge that RTK exists and make an informed choice that you still wish to stick with legacy Redux code. – markerikson Aug 11 '22 at 01:59
  • 1
    I did read them, i understand it's not going to get removed, what is frustrating folks is that "deprecated" almost always means "will be removed" and so they have to go google around to understand the risk of ignoring a warning that means "Must fix" for most code. e.g. i had to spend a some time finding this SO thread in order to understand it is safe to disable the build warnings we have complaining about deprecated code. – monastic-panic Aug 12 '22 at 21:15
  • In any case i popped in not to complain and take up your time, but to raise an additional use case for redux as part of other tools and so the message is confusing/misleading. Having read the linked articles i still think it would be a mistake to use RTK for our cases and that's fine – monastic-panic Aug 12 '22 at 21:16
  • 1
    This "deprecation" cost my team an hour today, and we're not going to use RTK because we already handled composing reducers and middlewares. This caused confusion in our team, and if you're not actually removing createStore from the API, it is unnecessary confusion. My opinion is that the right thing to do is removing the deprecation and adding notes to the documentation instead. – Mnebuerquo Oct 04 '22 at 20:19
  • @Mnebuerquo : sorry to hear that your team was confused, but the linked doc page clearly explains why we did this and why we _want_ people to use RTK instead. Note that it's not just about `configureStore` - it's also `createSlice` for simpler reducers and generating action creators, RTK Query for data fetching, and the other APIs included in RTK that make Redux usage better. (Note that we _could_ have published a major that actually _did_ remove `createStore`, but we didn't because we care about not breaking running code - thus the deprecation to give users notice that RTK exists.) – markerikson Oct 06 '22 at 00:00
  • Another person chiming in to say that using deprecation warnings this way seems like a mistake – robbie_c Nov 13 '22 at 16:20
  • @robbie_c: could you explain your thoughts further? I honestly don't understand this train of thought. Would folks have preferred that we actually _remove_ `createStore` in the next major version (which would of course _break_ working code)? The approach we took definitely fits the definition of "deprecated": "discouraging use of some terminology, feature, design, or practice, typically because it has been superseded or is no longer considered efficient or safe, without completely removing it or prohibiting its use". – markerikson Nov 14 '22 at 21:42
  • The approach I would have taken: keep the redux library as is, but make sure that all documentation makes it clear that rtk is the recommended way to create new applications. It sounds like this was already done, so no further action needed. – robbie_c Nov 15 '22 at 14:53
  • Changing the function name breaks semver, we bumped up a minor version (I believe 4.1.2 to 4.2.0) and due to createStore -> legacy_createStore, needed to do some unexpected work fixing this. To be clear, under semver, package maintainers are meant to keep forwards compatibility across minor version changes. If this is accidentally broken, the maintainers are meant to publish a patch version ASAP which fixes it. – robbie_c Nov 15 '22 at 14:55
  • See "What do I do if I accidentally release a backwards incompatible change as a minor version?" here https://semver.org/ – robbie_c Nov 15 '22 at 14:58
  • Of course the actual fix was trivial, but it still requires time and effort to understand the reasoning ("is it important that we actually change this soon? oh it turns out that it's just guidance for new projects, grumble") – robbie_c Nov 15 '22 at 15:00
  • (note: I said the "fixed" version that reverts the name createStore -> legacy_createStore should be a patch version, semver recommends it be a minor version, :shrug: less strong feelings there. I also appreciate it was't accidental, but the link is just intended to be an example of what to do in a similar situation) – robbie_c Nov 15 '22 at 15:05
  • Fundamentally, deprecating something is intentionally causing pain to your users. Usually this is for a good reason, e.g. because they will NEED to change how they use your code soon, and it's better for them if they adapt now rathern than later. This wasn't the case here, my understanding is that the redux team are not really suggesting that maintainers of pre-2019 codebases NEED to port their code to RTK, it's just a suggestion that they could consider it, and it's strongly recommended to use rtk for new projects. – robbie_c Nov 15 '22 at 15:08
  • 2
    @robbie_c : fwiw, I _very_ intentionally made sure that the "deprecation" only amounted to adding a `@deprecated` tag, which results in a visual strikethrough in an editor. No runtime warning. Existing code continues to run _exactly_ as-is, no changes, and thus _no_ semver breakage at all. In that sense, you didn't even _have_ to "fix" anything - you _could_ have left your code untouched and nothing would break. However, **we _absolutely_ want _all_ Redux users using RTK!** This was the only way we could reach out to many users who never look at our docs. (All clearly stated in the links) – markerikson Nov 16 '22 at 22:00
  • 1
    Apologies, I was wrong about semver – robbie_c Nov 23 '22 at 09:54
  • @markerikson If you want all users to use RTK you should provide an API and a set of tools that is as elegant, rich, testable as the method offered by combining saga and typesafe-actions. You can't say "it's deprecated, but nothing will break". You either state that we need to schedule a full refactoring or you state the opposite. – Davide Valdo Dec 02 '22 at 18:33
  • 1
    @DavideValdo : I'm... honestly not sure what you're saying there. The point of RTK has always been that you can use as much or as little as you want, and that you can either use it starting day 1 in a new Redux project _or_ incrementally migrate an existing project. It's _not_ an all-or-nothing proposition. Can you clarify what you mean by the "provide an API and set of tools" sentence? I don't know what you're trying to describe there. (We did recently add a "listener middleware" to RTK that's designed to replace most saga usages: https://redux-toolkit.js.org/api/createListenerMiddleware ) – markerikson Dec 03 '22 at 00:54
  • Most of all, I would be practically missing these patterns: https://redux-saga.js.org/docs/advanced/Channels. I'm guessing RTK Query might be the answer to my concern, but seems very different and hard to refactor starting from saga channels. – Davide Valdo Dec 04 '22 at 01:52
  • 2
    Yeah, the listener middleware was designed to do 80-90% of what sagas can do, in terms of responding to actions, running side effects, and even forking off "child tasks"... but channels are something we explicitly opted to _not_ implement. if you're using those, sagas _are_ actually a useful tool. – markerikson Dec 04 '22 at 03:00
  • Yeah I have a lot of code built upon the native Firebase SDK, which already handles caching quite comfortably. – Davide Valdo Dec 04 '22 at 17:29
  • https://redux.js.org/api/createstore should explain the deprecation. It doesn't mention it and doesn't mention Redux Toolkit. – Daniel Darabos May 11 '23 at 06:28
  • 1
    @DanielDarabos good point! Just filed https://github.com/reduxjs/redux/issues/4546 to cover this, and will try to get to it in the near future. – markerikson May 11 '23 at 23:39
  • 1
    I'm also here to express my strong discontent with deprecating createStore. One of the main appeal of react and redux was that it lends itself well to functional programming, and the enforced RTK alternative does the exact opposite. It doesn't follow the original philosophy of redux, it's more like a createReactApp for redux. If you want to advertise RTK, put it on the github and npm pages, not a cryptic deprecation. And if you want to force on people only using RTK with redux, go ask the owner to change the license. This isn't in the spirit of MIT license. – enrey May 15 '23 at 20:02
  • @enrey : I have to completely disagree with you on all levels. RTK _is still Redux_. You're still doing "functional programming". You're still creating a single store, and writing reducers with immutable updates. There's just less code to do both. Also, _we maintain all of the Redux libraries together_. We _are_ the owners. I have personally published _all_ of the recent Redux, React-Redux, Redux-Thunk, and RTK package versions. You can still use `createStore` if you want. But we strongly believe RTK is the best way to write Redux code and want _you_ to use it. – markerikson May 18 '23 at 14:36
  • @markerikson I'm not doing functional programming when I'm forced to use Immer as part of RTK. Also, you may believe that RTK is the best way to write redux code for your code, but judging by the backlash and my personal experience, it is not the best in a general case, so your belief may be a bit blind. The whole philosophy of redux was that it's just a one part of many, a simple functioning lib. RTK on the other hand is not that, it makes too many decisions for me. I don't want Immer, I want to use ramda. RTK just plain isn't able to do that. – enrey Jun 02 '23 at 09:30
  • @enrey : fwiw, the people complaining in this thread and a couple of our issues, despite the vocalness, are a _tiny_ minority. We get highly positive comments daily on how much people _love_ using RTK, and _love_ using Immer. So, yes, from that feedback I can safely say that RTK _is_ the best way to write Redux code. If you choose not to use it, that's _your_ decision. But as I've said, our job is to teach people what we firmly believe _is_ the best approach, and that includes pointing out that hand-written Redux is _not_ what we think they should be using. – markerikson Jun 03 '23 at 21:49
  • 1
    @markerikson I just found that createStore is deprecated, went looking on to why and found this thread. If something is DEPRECATED, it WILL BE REMOVED in future versions. Do not use deprecation flag as advertisement. That's just wrong. I use saga, can't refactor to RTK. As others said, put up a banner on your github repo, NOT IN DEPRECATION NOTICES. That's like if your coffee roaster would say "WARNING: Your favorite coffee is deprecated. Drink that one. It tastes different, you don't like it and you have to buy new machine for it, but we'll bombard you with WARNING again until you do. DO IT!" – Dalibor Filus Jun 23 '23 at 22:31
  • @DaliborFilus : as I've said repeatedly: "deprecation" _does not mean removal_. See my much longer answer at https://github.com/reduxjs/redux/discussions/4326#discussioncomment-6075581 . And again: all that changed was a visual strikethrough in the import. That's all. Also: you _can_ use sagas with RTK. You can use _any_ middleware with RTK and `configureStore`, because _it's still Redux_! _Please_ read all the links I posted in that answer to understand what RTK really is and how to use it. – markerikson Jun 24 '23 at 04:00
  • I generally try to adapt to recommended approaches over the time, but I didn't like that this "suddenly" broke my build pipeline (we have a pretty strict linter). -- And you say: _"you're following patterns that are much harder to use"_, but I find `createStore` pretty straight forward, at least for simple use cases. The `configureStore` / `createSlice` is harder to follow, IMO. (Thanks for answering here, though :)) – kca Jul 11 '23 at 09:21
  • @kca : we released Redux 4.2.0 a year ago, with a very clear update notice. We don't control your build pipeline or how strict your lint checks are. In this case, the deprecation notice is indeed doing its job and letting you know that RTK exists and that we _want_ you to use it. As mentioned, how you decide to handle that is now up to you. – markerikson Jul 12 '23 at 20:06
36

Also you can use import like this:

import { legacy_createStore as createStore } from 'redux';
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
Roman
  • 461
  • 4
  • 4
  • 2
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 05 '22 at 10:38
7

I was getting the same warning, and I did what VS code told me to do. I imported legacy_createStore.

import {legacy_createStore} from 'redux'

Or you can use an alias so that your code remains the same.

import {legacy_createStore as createStore} from 'redux'
Dennis Mwema
  • 81
  • 1
  • 2
1
  • The createStore is deprecated. You are creating a redux store using vanilla Redux. This pattern is much harder to use. That's why the creator of redux wants us to use Redux Toolkit. You can create store using Redux toolkit very easily. From Redux Toolkit you can use configureStore which wraps around createStore API and handle the store setup automatically.

  • In most cases, you should be using the configureStore method of the @reduxjs/toolkit package instead of calling createStore directly. As configureStore is calling createStore internally, it will not be going away, and your code will continue working but if you are just starting a new project, please be aware that we recommend using the official Redux Toolkit for any newly written Redux code since 2019.

    for more detail ===> https://redux.js.org/tutorials/fundamentals/part-8-modern-redux

0

Guys I am in 2023 and as of Redux >= version 4.0.0 , configureStore is the recommended way to create a Redux store using Redux Toolkit. Redux Toolkit's configureStore wraps around the original createStore method, and handles most of the store setup for us automatically, so initially install reduxjs/toolkit

npm install @reduxjs/toolkit

or if you are a yarn-er

yarn add @reduxjs/toolkit

and then where it's intended

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

That simple import explicitly applies middleware eg applyMiddleware, Redux Thunk and other middlewares for you. In my opinion less boilerplate code and just simplicity,and who wouldn't want that.