Switch store using condition in render using redux

2019-08-17 08:45发布

问题:

My application has 2 side, first side is the client app, second side is admin dashboard app. To make it DRY I decided to pass the store in the provider base on user role, so that I don't have to have 2 set of router.

class App extends Component {
  constructor(props) {
    super(props)

    this.role = getUserRole() //get role from localstorage
  }

  renderSwitchProvider = store => (
    <Provider store={store}>
      <BrowserRouter>
        <div className="App">
          <Switch>
            <Redirect exact from="/" to="/dashboard" />
            <Auth path="/dashboard" component={Dashboard} />

            <Route path="/login" component={Login} />
            <Route path="/signup" component={Signup} />
          </Switch>
        </div>
      </BrowserRouter>
    </Provider>
  )

  render() {
    if (this.role === 'member') {
      return this.renderSwitchProvider(store)
    } else if (this.role === 'admin') {
      return this.renderSwitchProvider(adminStore)
    }

    return null // problem is here
  }
}

export default App

But I got error of

Could not find "store" in either the context or props of "Connect(LoginForm)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(LoginForm)".

My getUserRole does this

export function getUserRole() {
  return (
    localStorage.getItem('token') &&
    jwtDecode(localStorage.getItem('token')).role
  )
}

回答1:

The problem is probably from getUserRole() this is a blocking task and this returns a null and role should not be null.

My suggestion here would be to have an APP component which resolves the value from getUserRole() and returns an Admin or User component based on the result from getUserRole()

Remove redux store implementation from App component and place implementation in individual Admin or User components.



回答2:

As you said, there are two sides client and admin.

So,you can assume default value for you store implementation.

Assume, you always want to load client store by default.

then render should be,

render() {

    if (this.role === 'admin') {
      return this.renderSwitchProvider(adminStore)
    }else if(this.role === 'member'){

        return this.renderSwitchProvider(store)
    }



}