Search code examples
reactjsreduxreact-reduxnext.jsnext-redux-wrapper

ERROR: Using UNSAFE_componentWillReceiveProps (NextJs / Redux)


Today I started to build a Next.js application. I am using Redux (next-redux-wrapper) to manage my global state. (I am also persisting some reducer with redux-persist). I just implemented redux-thunk and immediately got a very strange error. I really do not know why that error is occurring. I basically just did the setup, without creating any reducers (The error was still there, after I created the reducer). It is not the first time, I did the same setup without any problems, but that time I can not get rid of that error.

Error code

Warning: Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.***

  • Move data fetching code or side effects to componentDidUpdate.
  • If you're updating state whenever props change, refactor your code to use memoization ***techniques or move it to static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state Please update the following components: withRedux(MyApp)

If you need more code, please ask. I just do not really have much more. Maybe package.json.

_app.js

import App from 'next/app'
import { wrapper } from '../reduxStore/store'
import { useStore } from 'react-redux'
import PropTypes from 'prop-types'
function MyApp({ Component, pageProps }) {
  const store = useStore((state) => state)
  return <Component {...pageProps} />
}

MyApp.propTypes = {
  Component: PropTypes.func,
  pageProps: PropTypes.object,
}

export default wrapper.withRedux(MyApp)

store.js

    import { createStore, applyMiddleware, combineReducers } from 'redux'
import { HYDRATE, createWrapper } from 'next-redux-wrapper'
import thunkMiddleware from 'redux-thunk'
import userReducer from './reducers/userReducer'

const bindMiddleware = (middleware) => {
  if (process.env.NODE_ENV !== 'production') {
    const { composeWithDevTools } = require('redux-devtools-extension')
    return composeWithDevTools(applyMiddleware(...middleware))
  }
  return applyMiddleware(...middleware)
}

const combinedReducer = combineReducers({
  user: userReducer,
})

const reducer = (state, action) => {
  if (action.type === HYDRATE) {
    const nextState = {
      ...state, // use previous state
      ...action.payload, // apply delta from hydration
    }
    // if (state.count.count) nextState.count.count = state.count.count // preserve count value on client side navigation
    return nextState
  } else {
    return combinedReducer(state, action)
  }
}

export const makeStore = ({ isServer }) => {
  if (isServer) {
    //If it's on server side, create a store
    return createStore(reducer, bindMiddleware([thunkMiddleware]))
  } else {
    //If it's on client side, create a store which will persist
    const { persistStore, persistReducer } = require('redux-persist')
    const storage = require('redux-persist/lib/storage').default

    const persistConfig = {
      key: 'nextjs',
      whitelist: ['user'], // only counter will be persisted, add other reducers if needed
      storage, // if needed, use a safer storage
    }

    const persistedReducer = persistReducer(persistConfig, reducer) // Create a new reducer with our existing reducer

    const store = createStore(
      persistedReducer,
      bindMiddleware([thunkMiddleware]),
    ) // Creating the store again

    store.__persistor = persistStore(store) // This creates a persistor object & push that persisted object to .__persistor, so that we can avail the persistability feature

    return store
  }
}
export const wrapper = createWrapper(makeStore)

Solution

  • This is because the third party library is using componentWillReceiveProps - componentWillReceiveProps gets automatically renamed to UNSAFE_componentWillReceiveProps. This happens because those methods are now considered legacy code and React is deprecating that lifecycle method as well as others.

    Unfortunately, their isn't an immediate solution.

    • You can fork the code and update it yourself
    • Start an issue on the code's GIT page and hope the update their maintainer fixes the issue.
    • Find another library to do the same job.
    • Write custom logic to do the same thing as the library
    • Use the library and hope they fix it before it's deprecated by React.