Javascript Resact useState未在渲染时更新

Javascript Resact useState未在渲染时更新,javascript,reactjs,Javascript,Reactjs,因此,我试图让getAllEvents()仅在第一次呈现页面时运行,让getFilteredEvents()在更新/更改eventFilters时运行。我仍然希望在加载页面时运行getFilteredEvents(),以便将其传递到事件组件中进行呈现 但是,getFilteredEvents()似乎只在我使用FilterBar组件中的按钮修改eventFilters时运行,而不是在页面首次加载时运行。我可以通过在呈现哪个console.log()allEvents和filteredEvents之

因此,我试图让getAllEvents()仅在第一次呈现页面时运行,让getFilteredEvents()在更新/更改eventFilters时运行。我仍然希望在加载页面时运行getFilteredEvents(),以便将其传递到事件组件中进行呈现

但是,getFilteredEvents()似乎只在我使用FilterBar组件中的按钮修改eventFilters时运行,而不是在页面首次加载时运行。我可以通过在呈现哪个console.log()allEvents和filteredEvents之后按一个按钮来确认这一点,显示只填充了allEvents。但当我在呈现时console.log()allEvents in useEffect或getFilteredEvents时,它是空的。我还尝试将getFilteredEvents()放在页面render only Useffect中,但这也不起作用

  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>
  )
const[eventFilters,setEventFilters]=useState([“其他”、“车间”、“用餐”、“扬声器”、“迷你事件”);
const[allEvents,setAllEvents]=useState([]);
常量[filteredEvents,setFilteredEvents]=useState([]);
const something=()=>{
控制台日志(allEvents);
console.log(filteredEvents);
}
useffect(()=>{
getAllEvents();
setEventFilters(eventFilters.concat(“全部”));
}, []);
useffect(()=>{
getFilteredEvents();
},[eventFilters]);
const getAllEvents=async()=>{
const response=等待获取(URL);
const data=wait response.json();
setAllEvents(data.events);
};
常量getFilteredEvents=()=>{
log(“getFilteredEvents已运行”);
SetFilterEvents(allEvents.filter)(事件=>{
log(“正在填充filteredEvents”);
if(eventFilters.includes(event.eventType)){
返回{…事件}
}
}));
}
返回(
A.
2021年计划
)

当@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>
  )
const[eventFilters,setEventFilters]=useState([“其他”、“车间”、“用餐”、“扬声器”、“迷你事件”);
const[allEvents,setAllEvents]=useState([]);
常量[filteredEvents,setFilteredEvents]=useState([]);
const something=()=>{
控制台日志(allEvents);
console.log(filteredEvents);
}
useffect(()=>{
getAllEvents();
setEventFilters(eventFilters.concat(“全部”));
}, []);
useffect(()=>{
getFilteredEvents();
},[eventFilters]);
const getAllEvents=async()=>{
const response=等待获取(URL);
const data=wait response.json();
setAllEvents(data.events);
};
常量getFilteredEvents=()=>{
log(“getFilteredEvents已运行”);
SetFilterEvents(allEvents.filter)(事件=>{
log(“正在填充filteredEvents”);
if(eventFilters.includes(event.eventType)){
返回{…事件}
}
}));
}
如果(!filteredEvents){
return null//只是给出测试提示,出于实践目的,不要使用它。而是呈现一个显示等待状态的组件
}
返回(
A.
2021年计划
)

当@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>
  )
const[eventFilters,setEventFilters]=useState([“其他”、“车间”、“用餐”、“扬声器”、“迷你事件”);
const[allEvents,setAllEvents]=useState([]);
常量[filteredEvents,setFilteredEvents]=useState([]);
const something=()=>{
控制台日志(allEvents);
console.log(filteredEvents);
}
useffect(()=>{
getAllEvents();
setEventFilters(eventFilters.concat(“全部”));
}, []);
useffect(()=>{
getFilteredEvents();
},[eventFilters]);
const getAllEvents=async()=>{
const response=等待获取(URL);
const data=wait response.json();
setAllEvents(data.events);
};
常量getFilteredEvents=()=>{
log(“getFilteredEvents已运行”);
SetFilterEvents(allEvents.filter)(事件=>{
log(“正在填充filteredEvents”);
if(eventFilters.includes(event.eventType)){
返回{…事件}
}
}));
}
如果(!filteredEvents){
return null//只是给出测试提示,出于实践目的,不要使用它。而是呈现一个显示等待状态的组件
}
返回(
A.
2021年计划
)

这可能不是一个很好的解决方案,但它非常有效

  useEffect(() => {
    getAllEvents();
  }, []);

  useEffect(() => {
    getFilteredEvents();
  }, [allEvents]);

  useEffect(() => {
    getFilteredEvents();
  }, [eventFilters]);

我不知道为什么这是可行的,
setTimeout
不可行,但我甚至不在乎这一点。

这可能不是一个很好的解决方案,但它确实有效

  useEffect(() => {
    getAllEvents();
  }, []);

  useEffect(() => {
    getFilteredEvents();
  }, [allEvents]);

  useEffect(() => {
    getFilteredEvents();
  }, [eventFilters]);

我不知道为什么这会起作用,
setTimeout
不会起作用,但我甚至不关心这一点。

getFilteredEvents
肯定会在页面首次加载时运行。“问题”——如果它真的是一个问题的话——是
allEvents
仍然是空的,因为
getAllEvents
内部的异步调用还没有完成。这是完全正常的,如果使用异步代码,就无法避免。如果组件的实际运行方式是您不希望的-从用户的角度来看,而不仅仅是从
控制台.log
的角度来看-那么请详细解释问题所在,以便我们提供建议。尝试移动
setEventFilters(eventFilters.concat(“ALL”)
getAllEvents
函数中。如果这样做有效,我将对此进行解释。如果您没有在useEffect之外使用getAllEvents,则定义