Ввод HOC-компонента, связанного с Redux - PullRequest
0 голосов
/ 27 мая 2019

В моем компоненте Route у меня есть Layout HOC, некоторые компоненты которого имеют дочерние элементы.В этом HOC я отрисовываю верхнюю и боковую панели, а также подключаю его к моему хранилищу резервов, чтобы получить текущего пользователя и отправить действие выхода из системы.Проблема в том, что я определил реквизиты моего Hoc и поместил дочерние элементы как ReactNode, мой пользователь - как UserType, а действие выхода из системы - как функцию.Но в компоненте Маршрут я получаю сообщение об ошибке, потому что пользователь не передал и действие как реквизит.

Мой компонент HOC

interface Props extends RouteComponentProps {
  children?: ReactNode
  user?: UserType
  logoutAction(): void
}

const AppLayout = (props: Props) => (
  <Layout>
    {/* <Sidebar {...props} /> */}
    <Layout>
      {/* <TopBar user={props.user} /> */}
      <Content
        style={{
          margin: '24px 16px',
          padding: 24,
          background: '#fff',
          minHeight: 280
        }}
      >
        {props.children}
      </Content>
    </Layout>
  </Layout>
)
const mapStateToProps = (state: AppStateType, ownProps: Props) => ({
  ...ownProps,
  user: state.auth.currentUser
})

const mapDispatchToProps = (dispatch: Dispatch) => ({
  logoutAction: () => dispatch(logoutUserSuccessAction())
})

export default withRouter(
  connect(
    mapStateToProps,
    mapDispatchToProps
  )(AppLayout)
)

Мой компонент маршрута

class Routes extends React.Component<Props> {
  componentDidMount = () => {
    this.props.fetchFields()
    // this.props.fetchQuestions();
  }

  render() {
    return (
      <div
        style={{
          display: 'flex',
          height: '100vh',
          flexDirection: 'column',
          width: '100vw'
        }}
      >
        <AppLayoutContainer>
          <React.Fragment>
            <Switch>
              <Route path="/" exact component={HomePageContainer} />

              <Route path="/login" exact component={LoginPageContainer} />
              {/* NEED AUTH HOC */}
              <Route path="/gerencia" component={GerenciaPageContainer} />
              <Route path="/relatorio" component={ReportPageContainer} />
              <Route path="/exportar" component={ExportPageContainer} />
            </Switch>
          </React.Fragment>
        </AppLayoutContainer>
      </div>
    )
  }
}

Ошибка, которую я получил:

Property 'logoutAction' is missing in type '{ children: Element; }' but required in type 'Readonly<Pick<Pick<Props, never> & Props, "user" | "children" | "logoutAction">>'.ts(2741)
AppLayoutContainer.tsx(20, 3): 'logoutAction' is declared here.

Я пытаюсь ввести функцию соединения, но я получаю другую ошибку:

interface OwnProps extends RouteComponentProps {
  children?: ReactNode
  // user?: UserType
}

interface StateProps {
  user?: UserType
}

interface DispatchProps {
  logoutAction: () => void
}

type Props = StateProps & DispatchProps & OwnProps

const AppLayout = (props: Props) => (
  <Layout>
    {/* <Sidebar {...props} /> */}
    <Layout>
      {/* <TopBar {...props} /> */}
      <Content
        style={{
          margin: '24px 16px',
          padding: 24,
          background: '#fff',
          minHeight: 280
        }}
      >
        <Button onClick={() => props.logoutAction()}>Fazer Logout</Button>
        {props.children}
      </Content>
    </Layout>
  </Layout>
)

function mapStateToProps(
  state: AppStateType,
  ownProps: OwnProps
): StateProps & OwnProps {
  // ...ownProps,
  return {
    ...ownProps,
    user: state.auth.currentUser
  }
}

const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
  logoutAction: () => dispatch(logoutUserSuccessAction())
})

export default connect<StateProps, DispatchProps, void>(
  mapStateToProps,
  mapDispatchToProps
)(AppLayout)

, и я получаю эту ошибкусейчас:

Argument of type '(state: { auth: AuthReducerStateType; }, ownProps: OwnProps) => StateProps & OwnProps' is not assignable to parameter of type 'MapStateToPropsParam<StateProps, void, {}>'.
  Type '(state: { auth: AuthReducerStateType; }, ownProps: OwnProps) => StateProps & OwnProps' is not assignable to type 'MapStateToPropsFactory<StateProps, void, {}>'.
    Types of parameters 'state' and 'initialState' are incompatible.
      Property 'auth' is missing in type '{}' but required in type '{ auth: AuthReducerStateType; }'.ts(2345)
getReducers.ts(41, 3): 'auth' is declared here.

1 Ответ

1 голос
/ 27 мая 2019

Таким образом, logoutAction предоставляется редуксом, а не вами вручную.

Вы пометили эту опору как необходимую.Typescript не знает, что это избыточный компонент, и он пропустит этот проп, основываясь на mapDispatchToProps, поэтому он жалуется, что вы его не предоставили

В таком случае, когда какой-то проп, предоставляется внешним lib (redux в вашемcase) Обычно я отмечаю его как необязательный (что имеет смысл, потому что вы на самом деле не контролируете прохождение этой пропы)

interface Props extends RouteComponentProps {
  children?: ReactNode
  user?: UserType
  logoutAction()?: void // <<<--- ? added
}

Следует решить проблему

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...