首页 > 解决方案 > react redux 应用程序中未定义 state 或 props 中的课程

问题描述

我有一个简单的应用程序,其中包含课程组件。在 console.log 中打印未定义(对于状态和道具)。课程组件如下:

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));

courseApi.js 如下:

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)
        }
    }
}

courseActions.js 如下:

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))
}

courseReducer.js 如下:

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
    }
}

store.js 如下:

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__()

    )

);

文件夹结构如下: 1.courseActions.js 在_actions 文件夹中 2. coursApi.js 在_services 文件夹中 3.courseReducer.js 在_reducers 文件夹中 4.store.js 在_helper 文件夹中 5. ACTION_TYPES 在_constants 文件夹中。我将非常感谢您的帮助。错误是状态未定义。

标签: javascriptreactjsredux

解决方案


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

推荐阅读