首页 > 解决方案 > 为什么我的数组在 useEffect 之外是空的

问题描述

const [allJobs, setAllJobs] = useState([]);

 useEffect(() => {
        axios.get('http://localhost:3002/api/jobs')
            .then(res => setAllJobs(res.data));
        allJobs.map((job, i) => {
            if (job.language.toLowerCase() === currentLanguage) {
                jobsArray.push(job)
            }
            return jobsArray;
        })
        console.log(jobsArray)
    }, []);
const displayJobs = allJobs.map((job, i) => (
    <Accordion className={classes.accordion} expanded={expanded === `panel${i+1}`} onChange={handleChange(`panel${i+1}`)} key={i}>
// display stuff here
 ));

基本上我所做的是从我的 MongoDB 中获取所有作业并将它们保存在“allJobs”状态。

然后,根据他们拥有的字符串字段,代表他们编写的语言,我只需要过滤与我的“currentLanguage”var 具有相同语言的那些

我认为也是使用过滤器的一个好方法:

useEffect(() => {
   axios.get('http://localhost:3002/api/jobs')
       .then(res => setAllJobs(res.data));

   let result = allJobs.filter(job => job.language.toLowerCase() === currentLanguage);
   console.log(result)
}, []);

这返回了我在 useEffect 函数中需要的东西,但在它之外它只是一个空数组。我试过简单地退回它,但它并没有解决它。

从我读过的内容来看,它可能与异步有关,但我不知道我应该做什么。

标签: javascriptreactjsmongodbaxiosuse-effect

解决方案


正如您所读到的,setState它是异步的(Axios 也是如此)。这就是为什么您的代码意外地得到空数组的原因。

你会想要这样的东西与钩子很好地配合。

  • allJobsnull开始;什么都没有加载。
  • useEffect没有依赖,所以它只运行一次,在组件挂载上。
  • filteredJobs被记忆;无论何时allJobscurrentLanguage发生变化,都会重新计算。
  • 确保你已经配置了eslint-plugin-react-hooks,所以你遵守了 Hooks 规则
function JobComponent() {
  const [allJobs, setAllJobs] = useState(null);
  const [currentLanguage, setCurrentLanguage] = useState("fi");

  React.useEffect(() => {
    axios.get("http://localhost:3002/api/jobs").then((res) => setAllJobs(res.data));
  }, []);

  const filteredJobs = React.useMemo(
    () => (allJobs || []).filter((job) => job.language.toLowerCase() === currentLanguage),
    [allJobs, currentLanguage],
  );

  if (allJobs === null) {
    return <>Loading</>;
  }

  return filteredJobs.map((job, i) => (
    <Accordion
      className={classes.accordion}
      expanded={expanded === `panel${i + 1}`}
      onChange={handleChange(`panel${i + 1}`)}
      key={i}
    >
      // display stuff here
    </Accordion>
  ));
}

推荐阅读