I've created a menu component that I'd like to have redux manage the state of.
I have a MenuStore looks something like this:
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 };
};
And an Implementation like this:
export class App extends React.Component<AppProps, {}> {
public render(): any {
return <div>
<Menu />
{ this.props.children }
</div>;
}
}
Which yields this error:
TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly<{ children?: ReactNode; }> & Read...'. Type '{}' is not assignable to type 'Readonly'. Property 'isOpen' is missing in type '{}'.
Question:
- I realize that the component needs to be provided these state props... but to be honest... I don't know how.
Disclaimer. I'm still extremely novice with React & Redux... (Decided to jump into the thick of things) But when I use this same "pattern" for component loaded via the router, it works... so I'm guessing there is some magic happening in the background, where their props get loaded some other way. But as I'm manually creating the element <Menu /> that ability is lost..
(Also, I'm mirroring the dotnetcore react-redux's sample projects code (in terms of store layout etc, but this is my attempt at breaking out of the mold a bit and seeing how to do this)
Update (as this might be relevant)
My Menu component:
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);