React-Redux菜单?

时间:2017-09-20 16:05:44

标签: reactjs redux react-redux

我已经创建了一个菜单组件,我希望redux管理状态。

我有MenuStore看起来像这样:

export interface MenuState {
    isOpen: boolean;
}    

interface ToggleMenuAction {
    type: 'TOGGLE_MENU';
    isOpen: boolean;
}

export const actionCreators = {
    toggleMenu: (): AppThunkAction<ToggleMenuAction> => (dispatch, getState) => {
         dispatch({type: 'TOGGLE_MENU', isOpen: !getState().menu.isOpen});
    },
};

export const reducer: Reducer<MenuState> = (state: MenuState, action: ToggleMenuAction) => {
    if (action.type === 'TOGGLE_MENU') {
        return {
            isOpen: action.isOpen
        };
    }
    return state || { isOpen: false };
};

这样Implementation

export class App extends React.Component<AppProps, {}> {
    public render(): any {
        return <div>
            <Menu  />
            { this.props.children }
            </div>;
    }
}

产生此错误:

  

TS2322:类型'{}'不能分配给'IntrinsicAttributes&amp; IntrinsicClassAttributes&amp; Readonly&lt; {children?:ReactNode; }&GT;   &安培;读...'。         类型“{}”不能分配给“Readonly”类型。           “{}”类型中缺少属性“isOpen”。

问题:

  1. 我意识到组件需要提供这些状态道具......但说实话......我不知道如何。
  2. 声明。我仍然是React&amp; amp; Redux ...(决定跳入厚重的东西)但是当我使用相同的“模式”通过路由器加载的组件时,它的工作原理...所以我猜测在后台有一些魔法发生,其中他们的道具以其他方式加载。但是当我手动创建能力丢失的元素<Menu />时......

    (另外,我正在镜像dotnetcore react-redux的示例项目代码(就商店布局等而言,但这是我试图突破模具并看到如何做到这一点)

    <小时/> 更新(因为这可能相关)

    我的菜单组件:

    import * as React from 'react';
    import { connect } from 'react-redux';
    // other imports like "reactstrap", etc;
    
    import * as MenuStore from '../store/Menu';
    import {ApplicationState}  from '../store';
    
    // At runtime, Redux will merge together...
    type MenuProps =
        MenuStore.MenuState      
        & typeof MenuStore.actionCreators ;    
    export class Menu extends React.Component<MenuProps, {}> {      
    
        public render(): any {
    
            return <Navbar toggleable>
                <NavbarBrand href="/">
                    My App
                </NavbarBrand>
                <NavbarToggler onClick={ () => { this.props.toggleMenu(); } } />
                <Collapse isOpen={this.props.isOpen}>
                    <Nav navbar>
                        <NavLink>Something</NavLink>
                    </Nav>
                </Collapse>
            </Navbar>;
        }
    }
    
    export default connect(
        (state: ApplicationState) => state.menu, 
        MenuStore.actionCreators 
    )(Menu);
    

2 个答案:

答案 0 :(得分:1)

你绝对不应该为此目的使用Redux。 Redux旨在管理与整个应用程序相关的更广泛环境中的状态。与一个且仅一个组件相关的信息应由该组件本身管理。

那就是说,当你发现Redux时,你可以正确使用Redux,你似乎缺少的那块拼图是connect funtcion:https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options

答案 1 :(得分:0)

解决方案最终是从应用程序组件中提取菜单,并将其设置为路由器中的更高/超级根

export const routes = <App>
    <Route component={ Menu } />
    <Route exact path='/' component={ Home }/>
    <Route path='/search/:keywords?' component={ SearchResults }/>
    <Route path='/listing/:listingId' component={ Listing }/>
</App>;