[英]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.