mapStateToProps之后,道具仍然为空

时间:2019-01-18 00:27:28

标签: reactjs redux

我在一个现代堆栈应用程序中工作,当我尝试将状态传递给特定组件的道具时,会出错。

我得到了错误:

TypeError: Cannot read property 'items' of undefined

D:/Mohammed/project/mern-app/client/src/components/ShoppingList.js:19
  16 |        this.props.deleteItem(id);
  17 |    }
  18 | 
> 19 |    render() {
     | ^  20 |        const { items } = this.props.item;
  21 |    return (
  22 |      <div>

这是我的代码的存储库: https://github.com/mohamedsaad4/mern-app

这是mern-app / client / src / App.js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { Navbars } from './components/Navbar';
import { ShoppingList } from './components/ShoppingList';
import { Provider } from 'react-redux';
import store from './store';

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <div className="App">
          <Navbars />
          <ShoppingList />
        </div>
      </Provider>
    );
  }
}

export default App;

这是mern-app / client / src / components / ShoppingList.js

import React, { Component } from 'react';
import { Container, ListGroup, ListGroupItem, Button } from 'reactstrap';
import {  CSSTransition, TransitionGroup } from 'react-transition-group';
import { connect } from 'react-redux';
import { getItems, deleteItem } from '../actions/itemActions';
import PropTypes from 'prop-types';


export class ShoppingList extends Component {

    componentDidMount() {
        this.props.getItems();
    }

    deleteClick = (id) => {
        this.props.deleteItem(id);
    }

    render() {
        const { items } = this.props.item;
    return (
      <div>
          <Container>
              <ListGroup>
                  <TransitionGroup className="shopping-list">
                    {
                        items.map(({id, name}) => (
                            <CSSTransition key={id} timeout={500} classNames='fade'>
                                <ListGroupItem>
                                    <Button
                                        className='remove-btn'
                                        color='danger'
                                        size='sm'
                                        onClick={this.deleteClick.bind(this, id)}
                                    >&times;</Button>
                                     {name}
                                </ListGroupItem>
                            </CSSTransition>
                        ))
                    }
                  </TransitionGroup>
              </ListGroup>
          </Container>
      </div>
    )
  }
}

ShoppingList.propTypes = {
    getItems: PropTypes.func.isRequired,
    item: PropTypes.object.isRequired
}

const mapStateToProps = (state) => {
    return {
        item: state.item
    }
}

export default connect(mapStateToProps, { getItems, deleteItem })(ShoppingList);

这是mern-app / client / src / store.js

import { compose, applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const initialState = {};

const middleware = [thunk];

const store = createStore(rootReducer, initialState, compose(
   applyMiddleware(...middleware)
));

export default store;

这是mern-app / client / src / actions / itemActions.js

import { GET_ITEMS, ADD_ITEM, DELETE_ITEM } from './types';

export const getItems =  () => {
    return {
        type: GET_ITEMS
    };
};

export const deleteItem =  (id) => {
    return {
        type: DELETE_ITEM,
        payload: id
    };
};

这是mern-app / client / src / actions / types.js

export const GET_ITEMS = 'GET_ITEMS';
export const ADD_ITEM = 'ADD_ITEM';
export const DELETE_ITEM = 'DELETE_ITEM';

这是mern-app / client / src / reducers / index.js

import { combineReducers } from 'redux';
import itemReducer from './itemReducer';

export default combineReducers({
    item: itemReducer
});

最后是mern-app / client / src / reducers / itemReducer.js

import uuid from 'uuid';
import { GET_ITEMS, ADD_ITEM, DELETE_ITEM } from '../actions/types';

const initialState = {
    items: [
        {id: uuid(), name: 'ali'},
        {id: uuid(), name: 'amgad'},
        {id: uuid(), name: 'nour'},
    ]
};

export default function(state = initialState, action) {
    switch(action.type) {
        case GET_ITEMS:
            return {
                ...state
            }
        case DELETE_ITEM:
            return {
                ...state,
                items: state.items.filter(item => item.id !== action.payload)
            }
        default:
            return state;
    }
}

1 个答案:

答案 0 :(得分:1)

您不匹配连接的组件的导入和导出。

ShoppingList.js中,您拥有:

// Named export
export class ShoppingList extends Component {}

// Default export
export default connect(mapStateToProps, { getItems, deleteItem })(ShoppingList);

App.js中,您拥有:

// Named import
import { ShoppingList } from './components/ShoppingList';

因此,您正在导入ShoppingList未连接版本并使用它。

将其更改为默认导入,以便获得该组件的连接版本,并且应该可以正常工作:

import ShoppingList from './components/ShoppingList';