繁体   English   中英

使用带有 useEffect 的 async/promise

[英]Using async/promise with useeffect

我有我加载的 json 文件,我使用 Hook 来设置它。 在 SetState 之后,我想在我的函数中使用带有 Json 值的状态。 但是我的函数以空值执行,因为 setState 在 Execute 函数之前没有加载。 这是代码

 const fetchQuestions = async () => {
        const data = await require("../../question.json");
        await setQuestions(
            data.map((item: IQuestion) => ({
                    id: item.id,
                    question: item.question,
                    answers: item.answers
                })
            ))
        await setQuestionsArray(
            data.map((item: IQuestion) => ({
                    id: item.id,
                    name: item.question
                })
            ))
        return questionsArray
    }

有我通过 questionArray 的功能:

 const handleQuest = (array: Array<IArrayQuestion>) => {
        if (array.length > 0) {
            const numberArray = array.length
            const random = Math.floor(Math.random() * (numberArray - 0))
            const p = (array[random])
            setQuestion(p.name)
            setShuffleRandom(!shuffleRandom)
        }
    }

我在 useEffect 中使用它

useEffect(() => {
        if (nick.length < 1) {
            navigate('/quiz')
        }
        fetchQuestions().then((res)=>{
            if (questionsArray.length > 0){
                handleQuest(res)
            }
            else{console.log("Nothing")}
        })
    }, [])

它仍然不起作用。 承诺后我的职能没有价值

将数据获取逻辑与应用程序组件分开。 先写fetchQuestions

async function fetchQuestions() {
  const data = await require("../../questions.json")
  return data.map(item => ({
    id: item.id,
    question: item.question,
    answers: item.answers
  })
}

您的组件不应将数据复制到多个状态。 应该有一个 单一的事实来源 您不需要多个问题数组或当前问题的副本。 而是使用派生(计算)状态来引用“当前”问题 -

import { fetchQuestions } from "./api"

function MyComponent() {
  const [questions, setQuestions] = useState([])
  const [current, setCurrent] = useState(0)
  
  useEffect(async _ => {
    try {
      const q = await fetchQuestions()
      setQuestions(q)
      setCurrent(Math.floor(Math.random() * q.length)))
    }
    catch (err) {
      console.error(err.message)
    }
  ), [])

  return <div>
    <Question question={questions[current]} />
  </div>
}

您的Question组件看起来像这样 -

function Question({ question }) {
  return <div data-question-id={question.id}>
    Q: {question.name}
    {question.answers.map((answer, key) =>
      <Answer key={key} answer={answer} />
    )}
  </div>
}

编写Answer组件,依此类推...

需要在 useEffect 依赖中添加 questionsArray,但是因为是状态,所以应该在两个 useEffect 中做:

首先获取数据:

useEffect(() => {
    if (nick.length < 1) {
        navigate('/quiz')
    }
    fetchQuestions()
}, [])

而在第二次使用效果:

useEffect(() => {
    if (questionsArray.length > 0){
        handleQuest(questionsArray)
    }
    else{console.log("Nothing")}
}, [questionsArray])

当 questionsArray 处于 useEffect 依赖项时,每次 fetch 都会刷新并添加新问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM