因此,我试图让getAllEvents()仅在首次呈现页面时运行,并且让getFilteredEvents()在eventFilters更新/更改时运行。我仍然希望getFilteredEvents()在页面加载时运行,以便可以将其传递到Events组件中进行渲染。
但是,仅当我使用FilterBar组件中的按钮修改eventFilters时,getFilteredEvents()才似乎运行,而不是在首次加载页面时运行。我可以通过在渲染哪个console.log()allEvents和filteredEvents之后显示一个仅填充allEvents的按钮来确认这一点。但是当我在渲染时在useEffect或getFilteredEvents中使用console.log()allEvents时,它为空。我也尝试过将getFilteredEvents()放在仅页面渲染的useEffect内,但这也不起作用。
const [eventFilters, setEventFilters] = useState(["OTHER", "WORKSHOP", "MEAL", "SPEAKER", "MINIEVENT"]);
const [allEvents, setAllEvents] = useState([]);
const [filteredEvents, setFilteredEvents] = useState([]);
const something = () => {
console.log(allEvents);
console.log(filteredEvents);
}
useEffect(() => {
getAllEvents();
setEventFilters(eventFilters.concat("ALL"));
}, []);
useEffect(() => {
getFilteredEvents();
}, [eventFilters]);
const getAllEvents = async () => {
const response = await fetch(URL);
const data = await response.json();
setAllEvents(data.events);
};
const getFilteredEvents = () => {
console.log("getFilteredEvents has run");
setFilteredEvents(allEvents.filter(event => {
console.log("filteredEvents is being populated");
if(eventFilters.includes(event.eventType)){
return {...event}
}
}));
}
return (
<div className="App">
<button onClick={something}>a</button>
<Container>
<div>
<h1>2021 HackIllinois Schedule</h1>
</div>
<div>
<FilterBar eventFilters={eventFilters} setEventFilters={setEventFilters}/>
</div>
<Row>
<Col> <AllEvents filteredEvents={filteredEvents} selectedDay={selectedDay}/> </Col>
</Row>
</Container>
</div>
)
答案 0 :(得分:0)
正如@Robin突出显示的那样,您必须避免页面呈现,直到filteredEvents
具有值为止。您有两个选择,要么返回一个等待的组件,要么返回null
const [eventFilters, setEventFilters] = useState(["OTHER", "WORKSHOP", "MEAL", "SPEAKER", "MINIEVENT"]);
const [allEvents, setAllEvents] = useState([]);
const [filteredEvents, setFilteredEvents] = useState([]);
const something = () => {
console.log(allEvents);
console.log(filteredEvents);
}
useEffect(() => {
getAllEvents();
setEventFilters(eventFilters.concat("ALL"));
}, []);
useEffect(() => {
getFilteredEvents();
}, [eventFilters]);
const getAllEvents = async () => {
const response = await fetch(URL);
const data = await response.json();
setAllEvents(data.events);
};
const getFilteredEvents = () => {
console.log("getFilteredEvents has run");
setFilteredEvents(allEvents.filter(event => {
console.log("filteredEvents is being populated");
if(eventFilters.includes(event.eventType)){
return {...event}
}
}));
}
if(!filteredEvents){
return null // just giving this hint for testing, for practicle purpose don't use this. Instead render a component showing waiting state
}
return (
<div className="App">
<button onClick={something}>a</button>
<Container>
<div>
<h1>2021 HackIllinois Schedule</h1>
</div>
<div>
<FilterBar eventFilters={eventFilters} setEventFilters={setEventFilters}/>
</div>
<Row>
<Col> <AllEvents filteredEvents={filteredEvents} selectedDay={selectedDay}/> </Col>
</Row>
</Container>
</div>
)
答案 1 :(得分:0)
这可能不是一个很好的解决方案,但它确实起作用....
useEffect(() => {
getAllEvents();
}, []);
useEffect(() => {
getFilteredEvents();
}, [allEvents]);
useEffect(() => {
getFilteredEvents();
}, [eventFilters]);
我不知道为什么这行得通,setTimeout
却行不通,但现在我什至不在乎。