如何访问具有较高阶分量的状态

时间:2018-11-25 02:35:13

标签: reactjs redux higher-order-components

我想创建一个更高级别的组件来检查用户是否已经登录。如果有,我显示该组件,如果没有,我想将他们重定向到登录页面。

有人可以在这里解释我在做什么错吗?

这是HOC:

import React from 'react';
import { connect } from 'react-redux';

const withAuthentication = (Component) => {
  class WithAuthentication extends React.Component {
    componentDidMount() {
      console.log(this.props.sessionId);
    }

    render() {
      return this.props.sessionId ? <Component {...this.props} /> : null;
    }
  }

  const mapStateToProps = (state) => ({
    sessionId: state.auth.userInfo.authUserInfo.sessionId
  })
  return connect(mapStateToProps, null)(WithAuthentication);
}

export default withAuthentication;

然后我这样称呼它:

....
import withAuthentication from './containers/withAuthentication';
const Hello = () => <h1> Hello</h1>;
....
<Route path="/" component={ withAuthentication(Hello) }/>

我剥离了更多我认为与此无关的代码...

TIA为您提供帮助!

更新:导致问题的代码似乎是这样的:

const mapStateToProps = (state) => ({
sessionId: state.auth.userInfo.authUserInfo.sessionId
})

错误:TypeError: Cannot read property 'sessionId' of undefined

1 个答案:

答案 0 :(得分:0)

因此,基本上,您在将一个组件嵌套到另一个组件中时所做的工作,即功能组件在经过逻辑级别验证后返回了另一个组件。 你在做什么似乎很好。您应该能够在这样的功能组件中访问道具(而非状态)

const PricingType = new GraphQLObjectType({
  name: "Pricing",
  fields: () => ({
    expires: { type: GraphQLInt },
    private: { type: GraphQLBoolean },
    monthly: { type: GraphQLInt },
    scanEnvelope: { type: GraphQLInt },
    initalScan: { type: GraphQLInt },
    perPage: { type: GraphQLInt },
    forwardMail: { type: GraphQLInt },
    forwardParcel: { type: GraphQLInt },
    shred: { type: GraphQLInt },
    perMonthPerGram: { type: GraphQLInt },
    freeStorePerGram: { type: GraphQLInt },
    setup: { type: GraphQLInt },
    idFree: { type: GraphQLInt }
  })
})

const PlanType = new GraphQLObjectType({
  name: "Plan",
  fields: () => ({
    id: { type: GraphQLString },
    planName: { type: GraphQLString },
    pricing: { type: PricingType },
  }),
})

如果您正在使用这样的组件

DECLARE @deletedRows INT = 0;
SELECT @deletedRows = @@ROWCOUNT;   --no previous DML statement
SELECT @deletedRows;    --@@ROWCOUNT = 1 for a simple assignment
GO

DROP TABLE IF EXISTS #Test;
GO
CREATE TABLE #Test (ID INT IDENTITY, CurrentDate DATETIME DEFAULT GETDATE());
GO

INSERT #Test DEFAULT VALUES;    --INSERT a single row
DECLARE @deletedRows INT = @@ROWCOUNT;  --@@ROWCOUNT = 1 
SELECT @deletedRows;
GO

DELETE FROM #Test WHERE 1=2;    --no rows deleted
DECLARE @deletedRows INT = @@ROWCOUNT;  --@@ROWCOUNT = 0
SELECT @deletedRows;
GO

DELETE TOP (1) t FROM #Test t WHERE 1=1;    --1 row deleted
DECLARE @deletedRows INT = @@ROWCOUNT;  --@@ROWCOUNT = 1
SELECT @deletedRows;
GO

DELETE TOP (1) t FROM #Test t WHERE 1=1;    --no rows left to delete
DECLARE @deletedRows INT = @@ROWCOUNT;  --@@ROWCOUNT = 0
SELECT @deletedRows;
GO

此外,如果let aComponent(props)=>{ return <p>{props.name}'s logged in status is {props.loggedIn}</p> } 中的逻辑/身份验证失败,则应调用路由器API导航到所需页面。 即 如果您使用的是<aComponent title="Hello" loggedIn={this.props.isLoggedIn}/> //isLoggedIn from redux store

,则应调用此方法
withAuthentication