无法通过connect()将props传递给组件

时间:2017-10-08 01:25:08

标签: reactjs typescript redux

我正在使用React / Redux和TypeScript转换。我希望我的导航菜单从状态读取并保持其自己的迷你状态。

NavMenu.tsx:

import * as React from 'react';
import { NavLink, Link, RouteComponentProps } from 'react-router-dom';
import { connect } from 'react-redux';
import { ApplicationState } from '../store';
import * as NavigationStore from '../store/Navigation';

type NavigationProps =
  NavigationStore.NavigationState
  & typeof NavigationStore.actionCreators;

class NavMenu extends React.Component<NavigationProps, {}> {
  public render() {
    return (
      <nav className='main-nav'>
        <ul className={`nav-standard`}>
            <li>
                <NavLink exact to={'/'} activeClassName='active'>
                    Home
                </NavLink>
            </li>
            <li>
                <NavLink to={'/learn'} activeClassName='active'>
                    Learn
                </NavLink>
            </li>
            <li>
                <NavLink to={'/blog'} activeClassName='active'>
                    Blog
                </NavLink>
            </li>
        </ul>
        <div className='nav-small'>
          <button type='button' className='navbar-toggle' onClick={() => { this.props.toggle() } }>
              <span className='screen-reader-content'>Toggle Navigation</span>
              <i className='fa fa-bars'></i>
          </button>
        </div>
      </nav>
    );
  }
}

export default connect(
    (state: ApplicationState) => state.navigation,
    NavigationStore.actionCreators
)(NavMenu) as typeof NavMenu;

以下是我尝试渲染导航栏的方法,Layout.tsx:

import * as React from 'react';
import NavMenu from './NavMenu';

export class Layout extends React.Component<{}, {}> {
  public render() {
    return <div>
      <NavMenu />
      { this.props.children }
    </div>;
  }
}

我收到了打字稿格式错误:

TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<NavMenu> & Readonly<{ children?: ReactNode; }> & R...'. Type '{}' is not assignable to type 'Readonly<NavigationProps>'. Property 'expanded' is missing in type '{}'.

这不是connect()函数的目的吗?要自动将状态和操作映射到组件?这通常是我没有将props传递给组件时所得到的错误(不使用connect())。

修改 当我彻底传递NavigationProps类型所需的所有属性时,它确实有效:

import * as React from 'react';
import NavMenu from './NavMenu';

export class Layout extends React.Component<{}, {}> {
  public render() {
    return <div>
      <NavMenu expanded={false} expand={Navigation.actionCreators.expand} constrict={Navigation.actionCreators.constrict} toggle={Navigation.actionCreators.toggle} />
      { this.props.children }
    </div>;
  }
}
后代的

Navigation.ts(新导入):

import { Action, Reducer } from 'redux';

export interface NavigationState {
  expanded: boolean;
};

interface ExpandNavigationAction { type: 'EXPAND_NAVIGATION' }
interface ConstrictNavigationAction { type: 'CONSTRICT_NAVIGATION' }
interface ToggleNavigationAction { type: 'TOGGLE_NAVIGATION' }

type KnownAction = ExpandNavigationAction
  | ConstrictNavigationAction
  | ToggleNavigationAction;

export const actionCreators = {
  expand: () => <ExpandNavigationAction>{ type: 'EXPAND_NAVIGATION' },
  constrict: () => <ConstrictNavigationAction>{ type: 'CONSTRICT_NAVIGATION' 
},
  toggle: () => <ToggleNavigationAction>{ type: 'TOGGLE_NAVIGATION' }
};

export const reducer: Reducer<NavigationState> = (state: NavigationState, 
action: KnownAction) => {
  switch (action.type) {
    case 'EXPAND_NAVIGATION':
      return { expanded: true };
    case 'CONSTRICT_NAVIGATION':
        return { expanded: false };
    case 'TOGGLE_NAVIGATION':
        return { expanded: !state.expanded };
    default:
        const exhaustiveCheck: never = action;
  }
  return state || { expanded: false };
}

即使这成功转化,我这样做的目的是避免写出这样冗长的标记。我的印象是connect()方法的重点是通过mapper方法简单轻松地将状态下的正确属性传递给子组件。

1 个答案:

答案 0 :(得分:1)

不要将connect()的结果转换为typeof NavMenu。当你这样做时,你告诉TS该组件希望将NavigationProps对象作为属性传入。因此,当您没有传递任何属性时,您会收到错误。

connect()创建的包装组件没有必需的属性。