React - 使用 Context 向下传递数组变量,但是当有更新时,组件接收数组变量不会重新渲染

React - using Context to pass down array variable, but when there is an update, component receiving array variable not re-render

我正在使用 ContextexerciseList 数组变量传递给 2 个不同的组件,

ExerciseList 组件和 Exercise 组件。

Exercise 组件呈现单个练习,然后 ExerciseList 组件导入并实现它。

但是现在的问题是当有更新的时候, t.ex练习已被删除,所以ExerciseList应该重新渲染。

但除非我刷新页面,否则它不会发生。

这是我的 Context,

function ContextProvider(props) {
    const [ exerciseList, setExerciseList ] = useState([])

    useEffect(() => {
            axios.get('http://localhost:5000/exercises/')
            .then(response => {
                setExerciseList(response.data)
            })
            .catch(err => console.log(err))
    }, [])

    return (
        <Context.Provider value={{exerciseList,
                                  setExerciseList,
                                }}>
            {props.children}
        </Context.Provider>
    )
}

export { Context, ContextProvider }

并且我在 ExerciseList 组件中收到 exerciseList 这样的

export default function ExerciseList(){
    const { exerciseList } = useContext(Context)

    const exerciseData = exerciseList.map( exercise => (
        <Exercise key={exercise._id} 
                  id={exercise._id}
                  username={exercise.username} 
                  description={exercise.description} 
                  duration={exercise.duration}
                  date={exercise.date}
        />
    ))

    return(
        <div>
            <h3>Exercise List</h3>
            <table className="exercise-table"> 
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Description</th>
                        <th>Duration</th>
                        <th>Date</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    {exerciseData}
                </tbody>
            </table>
        </div>
    )
}

而我具有 delete 功能的 Exercise 组件是这样的

export default function Exercise({id, username, description, duration, date}) {
    const { setExerciseList } = useContext(Context)

    const deleteExercise = (id) => {
        axios.delete('http://localhost:5000/exercises/' + id)
            .then(res => console.log(res.data))
            .catch(err => console.log(err))

        setExerciseList(exercises => exercises.filter(exercise => exercise.id !== id))    
    }

    return (
        <tr>
           <td>{username}</td>
           <td>{description}</td>
           <td>{duration}</td>
           <td>{date}</td>
           <td>
                <Link to={"/edit/" + id}>edit</Link> | <button onClick={() => deleteExercise(id)}>delete</button>
           </td>
        </tr>
    )
}

我想知道为什么?我把 console.log(exerciseList.length > 0) 放在 ExerciseList 组件中, 看看它是否捕捉到数组的变化,但它没有。

求助!

你把 console.log(exerciseList.length > 0) 放在 ExerciseList 的什么地方了?如果你把它放在 exerciseList.map 上面,那么你应该会看到一些日志。


这可能是您遇到的问题。

useState 中的

setState 与 class 组件中的 this.setState 不同。

它不接受函数作为参数。

所以setExerciseList应该是这样

    const deleteExercise = (id) => {
        axios.delete('http://localhost:5000/exercises/' + id)
            .then(res => console.log(res.data))
            .catch(err => console.log(err))

        // setExerciseList(exercises => exercises.filter(exercise => exercise.id !== id))  
        setExerciseList(exercises.filter(exercise => exercise.id !== id))    
    }

注意:在删除UI中的项目之前,您应该确保axios.delete正常执行。例如,将 setExerciseList 移动到 .then 回调内部并为其提供一些更新状态。