这些技术的新手,对我的单页应用程序有疑问。我从这个模板中的reactredux示例开始:
我的SPA的根组件是布局。 NavMenu直接位于布局下以及RightNavMenu对象下。 RightNavMenu根据NavMenu的状态而变化,因此我在布局级别设置了NavMenu存储,如下所示:
index.ts:
import * as NavMenu from './NavMenu';
// The top-level state object
export interface ApplicationState {
navMenu: NavMenu.NavMenuState //-stores information on which index is currently selected
}
// Whenever an action is dispatched, Redux will update each top-level application state property using
// the reducer with the matching name. It's important that the names match exactly, and that the reducer
// acts on the corresponding ApplicationState property type.
export const reducers = {
navMenu: NavMenu.reducer
};
// This type can be used as a hint on action creators so that its 'dispatch' and 'getState' params are
// correctly typed to match your store.
export interface AppThunkAction<TAction> {
(dispatch: (action: TAction) => void, getState: () => ApplicationState): void;
}
这是我的NavMenu商店(NavMenu.ts): 从'redux'导入{Action,Reducer};
export interface NavMenuState {
selectedIndex: number;
}
interface SelectIndexAction { type: 'NAV_SELECT_INDEX' }
interface DoNothingAction { type: 'NAV_DO_NOTHING' }
type KnownAction = SelectIndexAction | DoNothingAction;
export const actionCreators = {
select: (selectedIndex:number) => <SelectIndexAction>{ type: 'NAV_SELECT_INDEX' },
donothing: () => <DoNothingAction>{ type: 'NAV_DO_NOTHING' }
};
export const reducer: Reducer<NavMenuState> = (state: NavMenuState, action: KnownAction) => {
switch (action.type) {
case 'NAV_SELECT_INDEX':
alert('hasdf');
return { selectedIndex: state.selectedIndex };
case 'NAV_DO_NOTHING':
return { selectedIndex: state.selectedIndex };
default:
// The following line guarantees that every action in the KnownAction union has been covered by a case above
const exhaustiveCheck: never = action;
}
// For unrecognized actions (or in cases where actions have no effect), must return the existing state
// (or default initial state if none was supplied)
return state || { selectedIndex: 0 };
};
这是我的NavMenu.tsx组件:
import * as React from 'react';
import { Link } from 'react-router';
import { connect } from 'react-redux';
import { ApplicationState } from '../store';
import { List, ListItem, makeSelectable } from 'material-ui/List';
import * as NavMenuStore from '../store/NavMenu';
let SelectableList = makeSelectable(List);
type NavMenuProps = NavMenuStore.NavMenuState
& typeof NavMenuStore.actionCreators
& { params: { startIndex: string } }; // ... plus incoming routing parameters
export class NavMenu extends React.Component<NavMenuProps, null> {
componentWillMount() {
// This method runs when the component is first added to the page
let selectedIndex = parseInt(this.props.params.startIndex) || 0; //parse the int or set to 0 if it fails
if (selectedIndex == 0) //if the parse fails select the first index by defaualt
selectedIndex = 1;
this.props.select(selectedIndex);
}
public render() {
return (
<SelectableList defaultValue={1}>
<p>Current index: <strong>{this.props.selectedIndex}</strong> </p>
<ListItem onClick={() => { this.props.select(1) }} value={1} primaryText="TestIndex1" />
<ListItem onClick={() => { this.props.select(2) }} value={2} primaryText="TestIndex2" />
</SelectableList>
);
}
}
export default connect(
(state: ApplicationState) => state.navMenu, // Selects which state properties are merged into the component's props
NavMenuStore.actionCreators // Selects which action creators are merged into the component's props
)(NavMenu);
最后,这就是我将它嵌入布局组件的方式:
<NavMenu />
上面引发了关于缺少属性的错误,所以我尝试更改为此,但它仍然无法正常工作。
<NavMenu donothing={null} params={null} selectedIndex={0} select={ null } />
有人可以告诉我我做错了什么吗?我目前只是想在列表顶部输出所选索引。当用户单击列表中的第一个或第二个项目时,我希望所选索引文本相应地更新。
问题:
我是否正确使用布局和右侧导航栏实现导航栏结构?
我如何才能让它发挥作用?
谢谢。
答案 0 :(得分:2)
这篇文章有点陈旧,但我想我会分享我的经验以防其他人遇到这个。我在同样的问题上打了2天,终于让它发挥了作用。
对我来说,它似乎归结为两件事。首先,我改变了:
export class NavMenu extends React.Component<NavMenuProps, null> {
并取消了&#34; export&#34;关键字:
class NavMenu extends React.Component<NavMenuProps, null> {
我猜测使用了export关键字,当你&#34;导入NavMenu&#34;在另一个组件中,它抓住了实际的NavMenu类,而不是Redux的Connect对象中包含的类。
另外,在我在标记中有NavMenu的Layout.tsx文件中,我显然有错误的import语句。我改成了:
import NavMenu from './NavMenu';
所有这些现在对我有用。 对不起,如果我的回答有点混乱或不准确。我对React很新,也不是很多javascript专家,所以请不要惹我生气......