web-dev-qa-db-ja.com

Reactルーター4.x-Reduxへの接続後にPrivateRouteが機能しない

例で使用可能なPrivateRoute https://reacttraining.com/react-router/web/example/auth-workflow は、Reduxに接続した後に機能しません。

私のPrivateRouteは元のバージョンとほとんど同じように見えますが、Reduxにのみ接続され、元の例ではfakeAuthの代わりにそれを使用しました。

const PrivateRoute = ({ component: Component, auth, ...rest }) => (
  <Route
   {...rest}
   render={props =>
   auth.isAuthenticated
    ? <Component {...props} />
    : <Redirect to={{ pathname: "/login" }} />}
  />
);

 PrivateRoute.propTypes = {
  auth: PropTypes.object.isRequired,
  component: PropTypes.func.isRequired
 }

 const mapStateToProps = (state, ownProps) => {
  return {
     auth: state.auth
  }
};

export default connect(mapStateToProps)(PrivateRoute);

使用方法と結果:-

  1. 機能していないがが望ましい&機能することが期待されている
    • <PrivateRoute path="/member" component={MemberPage} />
  2. 動作しますが、このように使用することは望ましくありません
    • <PrivateRoute path="/member" component={MemberPage} auth={auth} />
  3. ワーキング。動作するだけですが、まったく使用したくありません。この点からの理解は、元のPrivateRouteをReduxに接続する場合、PrivateRouteを機能させるためにいくつかの追加の小道具(任意の小道具)を渡す必要があることです。 どなたか、この動作に関するヒントを教えてください。これが私の主な質問です
    • <PrivateRoute path="/member" component={MemberPage} anyprop={{a:1}} />
13

react-reduxトラブルシューティングセクション で説明されているように、@ Tharakaの回答を補完して{pure: false}connectメソッドに渡すことができます。

React-reduxは、shouldComponentUpdateフック内の小道具の浅い比較を行い、不要な再レンダリングを回避します。コンテキストプロップが変更された場合(react-router)、それはチェックされず、何も変更されていないと想定します。

{ pure:false }は、この浅い比較を無効にするだけです。

12

react-router documentation によると、connect関数をwithRouterでラップするだけです:

// before
export default connect(mapStateToProps)(Something)

// after
import { withRouter } from 'react-router-dom'
export default withRouter(connect(mapStateToProps)(Something))

これでうまくいきました。

8

これはreact-reduxの既知の問題であり、この詳細については here を参照してください。問題はconnectです。HoCはshouldComponentUpdateを実装しているため、propsが変更されていない場合、ラップされたコンポーネントは再レンダリングされません。 react-routerはコンテキストを使用してルートの変更を渡すため、ラップされたコンポーネントはルートが変更されても再レンダリングされません。しかし、5.1バージョンのreact-reduxで remove shouldComponentUpdate を実行するようです。現在、回避策として、ルーター内からthis.props.match.paramsなどのプロップを接続された子コンポーネントに渡しますが、内部では使用しません。ただし、ルートが変更されるたびにコンポーネントが再レンダリングされます。

7