Реагировать - использование контекста для передачи переменной массива, но при обновлении компонент, получающий переменную массива, не повторно отображает

Я использую Context передать exerciseList переменная массива для двух разных компонентов,

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

И Exercise компонент, где у меня есть delete функция такая

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, чтобы увидеть, улавливает ли он изменение массива, а это нет.

Помогите!

1 ответ

Решение

Куда ты положил console.log(exerciseList.length > 0)в ExerciseList? Если вы поставите это вышеexerciseList.map тогда вы должны увидеть журнал.


Здесь может быть проблема, с которой вы столкнулись.

setState из useState это не то же самое, что 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))    
    }

Примечание: вы должны убедиться, чтоaxios.deleteработает правильно перед удалением элемента в пользовательском интерфейсе. Например, переместитеsetExerciseList быть внутри .then обратный вызов и дайте ему некоторое состояние обновления.

Другие вопросы по тегам