【问题标题】:React Hook useEffect has a missing dependency: 'props'. Either include it or remove the dependency array. props in useEffect have no dataReact Hook useEffect 缺少依赖项:'props'。包括它或删除依赖数组。 useEffect 中的道具没有数据
【发布时间】:2026-01-10 05:40:01
【问题描述】:

我使用 axios 在 react hooks 组件中调用 api 方法进行数据访问。我使用 react redux 进行状态管理。我从 useEffect 调用 fetchall 方法来获取所有课程。但是响应数组是空的并显示在上面的错误。状态或道具有问题。或者课程减速器没有获取数据。这里是 api.js 的代码。

import axios from "axios";

const baseUrl = "http://localhost:44306/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)
        }
    }
}

课程组件首先有 2 个网格,网格已被注释掉以专注于问题。第二个网格有表格,应该在表格中显示课程。后端表有很多行,这些行已经过邮递员和数据库的测试。 course.js 如下。

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



const styles = theme => ({
    root: {
        "& .MuiTableCell-head": {
            fontSize: "1.25rem"
        }
    },
    paper: {
        margin: theme.spacing(2),
        padding: theme.spacing(2)
    }
})





const Courses = ({ classes, ...props }) => {
    const [currentId, setCurrentId] =useState(0)
    useEffect(() => {
        props.fetchAllCourses()    // here is error props is empty

    }, [])//componentDidMount

    //toast msg.
    const { addToast } = useToasts()

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





    return (
        <Paper className={classes.paper} elevation={3}>
            <Grid container>
                <Grid item xs={6}>

                    {/* <CourseForm {...({ currentId, setCurrentId })} /> */}
                </Grid>
                <Grid item xs={6}>
                    <TableContainer>
                        { <Table>
                            <TableHead className={classes.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.Title}</TableCell>
                                            <TableCell>{record.Details}</TableCell>
                                            <TableCell>{record.Category}</TableCell>
                                            <TableCell>
                                                <ButtonGroup variant="text">
                                                    <Button><EditIcon color="primary"
                                                        onClick={() => { setCurrentId(record.id) }} /></Button>
                                                    <Button><DeleteIcon color="secondary"
                                                        onClick={() => onDelete(record.id)} /></Button>
                                                </ButtonGroup>
                                            </TableCell>
                                        </TableRow>)
                                    })
                                }
                            </TableBody>
                        </Table> }
                    </TableContainer>

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

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

const mapActionToProps = {
    fetchAllCourses: actions.fetchAll,
    deleteCourse: actions.Delete
}

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

actions中的course.js如下:

import api from "./api";

export const ACTION_TYPES = {
    CREATE: 'CREATE',
    UPDATE: 'UPDATE',
    DELETE: 'DELETE',
    FETCH_ALL: 'FETCH_ALL'
}

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

})

export const fetchAll = () => dispatch => {
    api.course().fetchAll()
        .then(response => {
            console.log(response)
            dispatch({
                type: ACTION_TYPES.FETCH_ALL,
                payload: response.data
            })
        })
        .catch(err => console.log(err))
}

export const create = (data, onSuccess) => dispatch => {
    data = formateData(data)
    api.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)
    api.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 => {
    api.course().delete(id)
        .then(res => {
            dispatch({
                type: ACTION_TYPES.DELETE,
                payload: id
            })
            onSuccess()
        })
        .catch(err => console.log(err))
}

reducer 中的 course.js 如下:

import { ACTION_TYPES } from "../actions/course";
const initialState = {
    list: []
}


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

    switch (action.ACTION_TYPES) {
        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
    }
}

为什么 useEffect 不访问道具。如何在 useEffect 中访问道具我将非常感谢您的帮助。 reducer 中的 index.js 如下:

import { combineReducers } from "redux";
import { course } from "./course";

export const reducers = combineReducers({
    course
})

提前致谢。

【问题讨论】:

    标签: reactjs redux


    【解决方案1】:

    似乎您需要将所需的依赖项传递给错误消息中提到的 useEffect。

    useEffect(() => {
      props.fetchAllCourses()
    }, [props.fetchAllCourses]);
    

    更新: 阅读 cmets 中的完整错误消息后,您似乎需要解构道具:

    const { fetchAllCourses } = props;
    
    useEffect(() => {
      fetchAllCourses();
    }, [fetchAllCourses]);
    

    【讨论】:

    • 这不起作用。同样的错误为什么它不获取记录?非常感谢您对我的问题感兴趣。
    • 我认为您提到了多个错误。问题的标题是关于缺少的依赖项,但您也提到它不获取记录。您关于依赖项的错误是否消失了,您是否陷入了另一个错误?
    • 不,@Orkun Tuzel 发生了同样的错误,请帮助我一整天都在这个麻烦中。状态和 props.useEffect() 有问题调用函数 fetchAll 但数据没有获取。
    • 这是错误:./src/components/Courses.js 第 33:9 行:React Hook useEffect 缺少依赖项:'props'。包括它或删除依赖数组。但是,当 any 道具发生变化时,“道具”会发生变化,因此首选的解决方法是在 useEffect 调用之外解构“道具”对象,并在 useEffect react-hooks/exhaustive- 中引用那些特定的道具部门
    • 您能在我的回答中查看我的更新吗?希望有效。
    【解决方案2】:

    您需要为 useEffect 提供依赖项,以便它可以观看。

    在您的课程组件中,修改此位

    useEffect(() => {
      props.fetchAllCourses()
    }, [props.fetchAllCourses]);
    
    

    【讨论】:

    • 感谢@sv12 的回复这不起作用。结果列表仍然是空的。
    【解决方案3】:

    上面的答案并没有解决我的问题,只是简单地向 useEffect() 的第二个参数添加道具解决了这个问题。

    useEffect(() => {
       props.fetchAllCourses()
    }, [props]);
    

    【讨论】:

    • 嗨,亲爱的@RAC!这取决于你是否解构道具。像'const { fetchAllCourses } = props;'你可以使用这个。在我的情况下,它就像上面一样。所以,@Orkun Tuzel 的答案对我有用。
    最近更新 更多