#javascript #reactjs
#javascript #reactjs
Вопрос:
Итак, я новичок в React и пытаюсь создать базовое приложение расписания. У меня есть четыре файла: «App.js «, «AllEvents.js «, «Event.js «, и «NavBar.js «
Мой App.js это довольно просто, и я включил только соответствующие части
const App = () => {
const [eventFilters, setEventFilters] = useState([]);
const [allEvents, setAllEvents] = useState([]);
useEffect(() => {
getAllEvents();
}, []);
const getAllEvents = async () => {
const response = await fetch(URL);
const data = await response.json();
setAllEvents(data.events);
};
return (
<div className="App">
<NavBar eventFilters={eventFilters} setEventFilters={setEventFilters}/>
<AllEvents allEvents={allEvents} eventFilters={eventFilters}/>
</div>
)
}
В AllEvents.js Я на самом деле визуализирую события, которые я получаю от getAllEvents() в App.js
import React, { useState, useEffect } from 'react';
import Event from './Event';
const AllEvents = ({allEvents, eventFilters}) => {
const [filteredEvents, setFilteredEvents] = useState([]);
const getFilteredEvents = () => {
setFilteredEvents(allEvents.filter(event => eventFilters.includes(event.eventType)));
}
useEffect(() => {
getFilteredEvents();
}, [eventFilters.length]);
return(
<div>
{filteredEvents.map((event) => (
<Event
key={event.id}
title={event.name}
description={event.description}
type={event.eventType}
/>
))}
</div>
);
}
В NavBar.js Я устанавливаю фильтры событий в зависимости от того, какие кнопки нажаты
const navBar = ( {eventFilters, setEventFilters} ) => {
const eventFilterHandler = (e) => {
var passedFilter = e.target.value;
var arrayContainsFilter = false;
for(var i = 0; i < eventFilters.length; i ){
if(eventFilters[i] == passedFilter){
eventFilters.splice(i, 1);
setEventFilters(eventFilters);
arrayContainsFilter = true;
}
}
if(!arrayContainsFilter){
setEventFilters(eventFilters.concat(passedFilter));
}
console.log(eventFilters);
};
return(
<div>
<div onClick={eventFilterHandler}>
<button value="ALL"> All </button>
<button value="WORKSHOP"> Workshop </button>
<button value="MINIEVENT"> Minievent </button>
<button value="SPEAKER"> Speaker </button>
<button value="MEAL"> Meal </button>
<button value="OTHER"> Other </button>
</div>
</div>
);
}
Когда я добавляю значения в eventFilters, нажимая на кнопки, useEffect в AllEvents.js запускает и повторно отображает страницу. Однако, когда я удаляю значения, useEffect не запускается, и страница не отображается повторно. Кто-нибудь знает почему?
Ответ №1:
Проблема в том:
for(var i = 0; i < eventFilters.length; i ){
if(eventFilters[i] == passedFilter){
eventFilters.splice(i, 1);
setEventFilters(eventFilters);
arrayContainsFilter = true;
}
}
if(!arrayContainsFilter){
setEventFilters(eventFilters.concat(passedFilter));
}
В цикле вы изменяете существующее состояние (никогда не делайте этого в React!) и передаете измененное состояние функции set state . Поскольку старое состояние ===
переходит в новое состояние, повторный рендеринг отсутствует.
Никогда не изменяйте состояние в React. Вместо этого создайте копию. Здесь вы можете использовать filter
:
if (eventFilters.includes(passedFilter)) {
setEventFilters(
eventFilters.filter(item => item !== passedFilter)
);
} else {
setEventFilters(eventFilters.concat(passedFilter));
}
Ответ №2:
Насколько я понимаю, вы хотите повторно отобразить компонент после изменения данных.Но он изменяется только при добавлении данных, а не при их удалении.Это может быть связано с тем, что useEffect вы запускаете его только при получении данных.Ранее
useEffect(() => {
getAllEvents();
}, []);
Теперь
useEffect(() => {
getAllEvents();
}, [allEvents]);
Запустите useEffect при изменении данных.Если оно удалено или добавлено