Reactjs 反应&;Redux:无法读取未定义的属性

Reactjs 反应&;Redux:无法读取未定义的属性,reactjs,redux,Reactjs,Redux,我正试图用react编写一个应用程序,我面临着必须管理这么多组件的状态的问题,所以我想使用redux。据我所知,Redux不适用于根组件,因此我创建了一个名为“包装器”的中间组件,它将包装所有内容并管理应用程序的状态。现在我有了我的原始根组件和包装器组件。我正在尝试使用redux在这个包装器组件中获得一些道具,但是由于某些原因,这些道具没有被填充,我无法理解 这是我的密码: import * as React from 'react' import { Provider } from "reac

我正试图用react编写一个应用程序,我面临着必须管理这么多组件的状态的问题,所以我想使用redux。据我所知,Redux不适用于根组件,因此我创建了一个名为“包装器”的中间组件,它将包装所有内容并管理应用程序的状态。现在我有了我的原始根组件和包装器组件。我正在尝试使用redux在这个包装器组件中获得一些道具,但是由于某些原因,这些道具没有被填充,我无法理解

这是我的密码:

import * as React from 'react'
import { Provider } from "react-redux";
import { connect } from "react-redux";
//SPFX references
import { DefaultButton, IButtonProps } from 'office-ui-fabric-react/lib/Button';
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel';

//custom references
import { IRootProps } from '../props/IRootProps'
import { IRootState } from '../states/IRootState'
import { ITile, ITileHeader, ITileItem } from '../props/ITileStructure'
import store from '../main/store'
import { openPanel, closePanel } from '../actions/panelAction'

//Styles references
import rootStyles from '../styles/RooComponent.module.scss'
import commonStyles from '../styles/common.module.scss'

//Components references
import PanelComponent from './PanelComponent'
import FooterComponent from './FooterComponent'
import DiscardChangesDialogComponent from './DiscardChangesDialogComponent'
import BladesRootComponent from './BladesRootComponent'
import TilesListComponent from './TilesListComponent'

class RootComponent extends React.Component<{}, {}>{
    tiles: ITile[] = [];

    constructor(props) {
        super(props);
    }

    render(): JSX.Element {
        return (
            <Provider store={store}>
                <AppWrapper />
            </Provider>

        )
    }
}

class AppWrapper extends React.Component<IRootProps, IRootState>{
    tiles: ITile[] = [];

    constructor(props: IRootProps) {
        super(props);

        if (this.tiles.length === 0) {
            for (let i = 0; i < 200; i++) {
                this.tiles.push({
                    key: i,
                    tileName: 'tile ' + i,
                    tileImageUrl: 'image url ' + i,
                    tileOrder: i,
                    headers: []
                });
            }
        }
    }
    render(): JSX.Element {
        return (
            <div className="RootComponent">
                <DefaultButton onClick={() => this.props.panelProps.openPanel()} className={commonStyles.defaultButton} >Configure Tiles</DefaultButton>
                <Panel
                    isOpen={this.props.panelProps.isPanelOpen}
                    // tslint:disable-next-line:jsx-no-lambda
                    onDismiss={() => {
                        this.setState({ showPanel: false })
                    }}
                    type={PanelType.extraLarge}
                    headerText="Tiles configuration"
                    hasCloseButton={false}>
                    <PanelComponent />
                </Panel>
            </div>
        )
    }
}

let mapStateToProps = (state) => {
    return {
        panelProps: state.panel,
    };
};

let mapDispatchToProps = (dispatch) => {
    return {
        openPanel: () => {
            dispatch(openPanel());
        }
    };
};

connect(mapStateToProps, mapDispatchToProps)(AppWrapper);
export default RootComponent; 
和../reducers/panelReduce如下所示:

//(state, action) => 
const panelReducer = (state = {
    isPanelOpen: false
}, action) => {
    switch (action.type) {
        case "OPEN_PANEL":
            state = {
                ...state,
                isPanelOpen: true
            };
            break;
        case "CLOSE_PANEL":
            state = {
                ...state,
                isPanelOpen: false
            };
            break;
    }
    return state;
};

export default panelReducer;

但是,代码正在执行,并且在以下行:
事实上,您没有在
根组件中使用连接的
AppWrapper
组件

您可以创建一个常量AppWrapperConnected:
const AppWrapperConnected=connect(mapStateToProps,mapDispatchToProps)(AppWrapper)并在
根组件中使用

此外,我认为如果将
RooComponent
AppWrapper
拆分为两个单独的文件,那么维护起来会更容易

另一个建议是像这样重写
MapStateTops

let mapStateToProps = (state) => state.panel

因此,您可以直接使用
this.props.isPanelOpen
,我认为
panelProps
在这里是无用的

事实上,您没有在
根组件中使用连接的
AppWrapper
组件

您可以创建一个常量AppWrapperConnected:
const AppWrapperConnected=connect(mapStateToProps,mapDispatchToProps)(AppWrapper)并在
根组件中使用

此外,我认为如果将
RooComponent
AppWrapper
拆分为两个单独的文件,那么维护起来会更容易

另一个建议是像这样重写
MapStateTops

let mapStateToProps = (state) => state.panel


因此,您可以直接使用
this.props.isPanelOpen
,我认为
panelProps
在这里是无用的

应该是this.props.isPanelOpen,因为这里没有名为
panelProps
的属性,但我想组合多个减速机。在我的store文件中,我让``store=createStore(combineReducers({```这样在props和.isPanelOpen?之间就不会有另一个对象了。另外,当我记录这个.props时,它给我这个{}你试过
让store=createStore(combineReducers({panel}));
而不是
让store createStore(combineReducers({panel}),{});
?基本上,您将初始状态设置为
{}
,这样它就不起作用了…@CRayen
panelProps
是在mapstateTrops函数中定义的,因此
this.props.panelProps.isPanelOpen
是correct@CRayen我像这样尝试过让store=createStore(combineReducers({panel}));…相同的错误应该是this.props.isPanelOpen,因为没有名为
panelProps
Hi-CRayen的属性,但我想组合多个减缩器。在我的存储文件中,我让``store=createStore(组合减缩器({```那么在props和.isPanelOpen?之间就不会有另一个对象了。当我记录这个.props时,它给了我这个{}你有没有尝试过
let store=createStore(combineReducers({panel}));
而不是
let store=createStore(combineReducers({panel}),{});
?基本上你把初始状态设置为
{}
因此它将不起作用…@CRayen
panelProps
是在MapStateTrops函数中定义的,因此
此.props.panelProps.isPanelOpen
是correct@CRayen我像这样尝试过让store=createStore(combineReducers({panel}));…同样的错误谢谢@Olivier。但是我如何重新分配AppWrapper..我刚试过,它说它不是一个变量。因为它是一个类组件。我编辑了我的答案,你使用
让AppWrapper=class extends React.component…
或者创建一个新变量
AppWrapperConnected
,顺便问一下,为什么要从状态中删除panelProps?什么如果我有另一个属性与其他同名的东西相关?是的,但在这里它似乎没用,因为你没有另一个同名的道具…好的。谢谢你:DThanks@Olivier。但是我如何重新分配AppWrapper。我刚刚试过,它说它不是变量。因为它是类组件。我编辑了我的答案,你使用
let AppWrapper=类扩展React.Component…
或创建一个新变量
AppWrapperConnected
顺便问一下,为什么要从状态中删除panelProps?如果我有另一个与其他同名属性相关的属性怎么办?是的,但在这里它似乎没用,因为您没有另一个同名的属性…好的。谢谢:D