Reactjs 无法通过connect()将道具传递给组件

Reactjs 无法通过connect()将道具传递给组件,reactjs,typescript,redux,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 '../st

我正在使用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;
Navigation.ts
面向后代(新导入):

从'redux'导入{Action,Reducer};
导出接口导航状态{
扩展:布尔;
};
接口ExpandNavigationAction{type:'EXPAND_NAVIGATION'}
接口压缩导航操作{type:'construct_NAVIGATION'}
接口ToggleNavigationAction{type:'TOGGLE_NAVIGATION'}
类型KnownAction=ExpandNavigationAction
|收缩作用
|ToggleNavigationAction;
导出常量actionCreators={
展开:()=>{type:'expand_NAVIGATION'},
压缩:()=>{type:'construct_NAVIGATION'
},
切换:()=>{type:'toggle_NAVIGATION'}
};
导出常量减速机:减速机=(状态:NavigationState,
操作:KnownAction)=>{
开关(动作类型){
案例“扩展导航”:
返回{expanded:true};
案例“压缩导航”:
返回{扩展:false};
案例“切换导航”:
返回{expanded:!state.expanded};
违约:
const defactvecheck:从不=操作;
}
返回状态| |{扩展:false};
}

尽管这成功地实现了透明,但我这样做的目的是避免写出如此冗长的标记。我的印象是,connect()方法的全部要点是通过映射器方法简单方便地将正确的属性从状态传递到子组件。

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


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

您的编辑代码是否在某个地方设置了
expanded
state属性?看起来您为
state
类型指定了空对象,但后来设置了
state.expanded
。我编辑了该代码只是为了简洁,我已将其添加到原始文章中。没有对state.expanded的引用,但我想如果我手动将每个属性传递给组件,这将再次开始传输。我会这样做,并用对文章的编辑来更新你。再次更新问题,如果我传递所有类型,它确实有效,但使用connect()方法的目的是避免如此冗长。哇,它真的就这么简单!对于任何试图在VS2017中扩展.NET Core 2.0样板文件的人来说都很有用,我只是延续了之前使用的模式。
import * as React from 'react';
import NavMenu from './NavMenu';

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