Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using higher order components with Redux containers

First, some context.

I'm using Redux to manage authentication state of my app and have Auth as a Redux container (or smart component).

I've created a wrapper (a higher-order component) that takes Auth and returns it:

export default function AuthWrapper(WrappedComponent) {
  class Auth extends Component {
  ... <Auth stuff here> ...
  }
  return connect(mapStateToProps, mapDispatchToProps)(Auth);
}

It seems to me that in order to use the wrapper, I just need to invoke it with a component I want to have behind my auth. For example, let's say I'm authenticating a component called UserPage with the wrapper, à la:

const AuthenticatedUserPage = AuthWappper(UserPage)

However, when I use the wrapper like this, React isn't happy with me. I get the following error:

Warning: AuthenticatedApp(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

My best guess is that it doesn't like the connect-ified component that Redux will create when I return it from AuthWrapper... which leads me to my question:

Does React support higher-order components when those components create Redux containers? And if so, why would React be throwing this error?

like image 265
Smee Avatar asked Mar 01 '17 04:03

Smee


1 Answers

Here's my two cents. I think the error is occurring elsewhere.

According to this simplified version of the connect function in react-redux, the connect function is simply returning another react component. So in your case, you're returning a component, wrapped inside another component, which is still valid. A container is basically a component.

Read https://gist.github.com/gaearon/1d19088790e70ac32ea636c025ba424e for a better understanding of the connect function.

I also tried the following in my own application and it worked.

import Layout from '../components/Layout'
//Do some other imports and stuff
function wrapper(Layout) {
  return connect(null, mapDispatchToProps)(Layout);
}
export default wrapper()

Like the error states, you might just simply be returning an invalid component somewhere in your app. Your app might be throwing the error because you're not wrapping a return call in parentheses on your render method.

like image 57
Sean Kwon Avatar answered Oct 31 '22 02:10

Sean Kwon