简体   繁体   中英

the course in state or props is undefined in react redux app

i have a simple app which have Courses component.in the console.log prints undefined(for both state and props). the Courses component is as:

import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { useSelector } from "react-redux";
import { styles } from "../_helpers";
import * as actions from "../_actions";
import EditIcon from "@material-ui/icons/Edit";
import DeleteIcon from "@material-ui/icons/Delete";
import  { useToasts } from "react-toast-notifications";
import { Grid, Paper, TableContainer, Table, TableHead, TableRow, TableCell, TableBody, withStyles, ButtonGroup, Button } from "@material-ui/core";


 export const Courses =(props)=> {

    useEffect(() => {
        actions.fetchAll();
    }, [])//componentDidMount
       console.log(props.course);//course is undefined
    //toast msg.
    const { addToast } = useToasts()

    const onDelete = id => {
        if (window.confirm('Are you sure to delete this record?'))
            props.delete(id,()=>addToast("Deleted successfully", { appearance: 'info' }))
    }
    function handleClick(id) {
         (window.alert('you want to edit?'))
    }




    return (
        <Paper className={styles.paper} elevation={3}>

            <Grid container>
                <Grid item xs={6}>

                    {/* <CourseForm{...({ currentId, setCurrentId })}/> */}

                </Grid>
                <Grid item xs={6}>
                    <TableContainer>
                        { <Table>
                            <TableHead className={styles.root}>
                                <TableRow>
                                    <TableCell>Title</TableCell>
                                    <TableCell>Details</TableCell>
                                    <TableCell>Category</TableCell>
                                    <TableCell></TableCell>
                                </TableRow>
                            </TableHead>

                            <TableBody>
                                {

                                props.courseList.map((record, index) => {
                                        return (<TableRow key={index} hover>

                                            <TableCell>{record.courseTitle}</TableCell>
                                            <TableCell>{record.details}</TableCell>
                                            <TableCell>{record.category}</TableCell>
                                            <TableCell>
                                                <ButtonGroup variant="text">
                                                    <Button><EditIcon color="primary"
                                                        onClick={() => handleClick(record.courseId) } /></Button>
                                                    <Button><DeleteIcon color="secondary"
                                                        onClick={() => onDelete(record.courseId)} /></Button>
                                                </ButtonGroup>
                                            </TableCell>
                                        </TableRow>)
                                    })
                                }
                            </TableBody>
                        </Table> }
                    </TableContainer>

                </Grid>
            </Grid>
        </Paper>
    );

}

const mapStateToProps = state => ({
    courseList: state.course.list
})




 export default connect(mapStateToProps)(withStyles(styles)(Courses));

the courseApi.js is as:

import axios from "axios";

const baseUrl = "https://localhost:4000/api/"



 export default {

      course(url = baseUrl + 'courses/') {
        return {
            fetchAll: () => axios.get(url),
            fetchById: id => axios.get(url + id),
            create: newRecord => axios.post(url, newRecord),
            update: (id, updateRecord) => axios.put(url + id, updateRecord),
            delete: id => axios.delete(url + id)
        }
    }
}

the courseActions.js is as:

import courseApi from "../_services/courseApi";
import { ACTION_TYPES } from '../_constants';


const formateData = data => ({
    ...data,

})

export const fetchAll = () => dispatch => {
      courseApi.course().fetchAll()
        .then(response => {

            dispatch({
                type: ACTION_TYPES.FETCH_ALL,
                payload: response.data
            })
        })
        .catch(err => console.log(err))
}

export const create = (data, onSuccess) => dispatch => {
    data = formateData(data)
      courseApi.course().create(data)
        .then(res => {
            dispatch({
                type: ACTION_TYPES.CREATE,
                payload: res.data
            })
            onSuccess()
        })
        .catch(err => console.log(err))
}

export const update = (id, data, onSuccess) => dispatch => {
    data = formateData(data)
      courseApi.course().update(id, data)
        .then(res => {
            dispatch({
                type: ACTION_TYPES.UPDATE,
                payload: { id, ...data }
            })
            onSuccess()
        })
        .catch(err => console.log(err))
}

export const Delete = (id, onSuccess) => dispatch => {
      courseApi.course().delete(id)
        .then(res => {
            dispatch({
                type: ACTION_TYPES.DELETE,
                payload: id
            })
            onSuccess()
        })
        .catch(err => console.log(err))
}

the courseReducer.js is as follows:

import { ACTION_TYPES } from '../_constants';
const initialState = {
    list: []
}


export const course = (state = initialState, action) => {

    switch (action.type) {
        case ACTION_TYPES.FETCH_ALL:
            return {
                ...state,
                list: [...action.payload]
            }

        case ACTION_TYPES.CREATE:
            return {
                ...state,
                list: [...state.list, action.payload]
            }

        case ACTION_TYPES.UPDATE:
            return {
                ...state,
                list: state.list.map(x => x.id == action.payload.id ? action.payload : x)
            }

        case ACTION_TYPES.DELETE:
            return {
                ...state,
                list: state.list.filter(x => x.id != action.payload)
            }

        default:
            return state
    }
}

the store.js is following:

import { createStore, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk';
import { createLogger } from 'redux-logger';
import rootReducer from '../_reducers';

const loggerMiddleware = createLogger();

export const store = createStore(
    rootReducer,
    applyMiddleware(
        thunkMiddleware,
        loggerMiddleware
        //window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()

    )

);

the folder structure is as follows: 1.courseActions.js is in _actions folder 2. coursApi.js is in _services folder 3.courseReducer.js in _reducers folder 4.store.js is in _helper folder 5. ACTION_TYPES is in _constants folder. i will be very thankful for kind help. the error is that state is undefined.

i changed the Courses component and used useSelector() and useDispatch() function instead of connect.this way i was able to access the state.i removed the props argument from functional component Courses.more over removed mapStateToProps and connect completely.i am sharing so that may be helpful for anyone.

export const Courses =()=> {
 const course = useSelector(state => state.course);
    const dispatch = useDispatch();
 console.log(course);
    useEffect(() => {
        dispatch(actions.fetchAll());
    }, [])//componentDidMount
//other stuff

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM