开发者问题收集

未捕获 TypeError:无法读取未定义的属性(读取“question”)。这是在使用 useState() 设置来自 GET 请求的数据之后发生的

2022-08-09
3487

我正在发出一个简单的 GET 请求,并希望使用 useState() 使该数据更易于访问,但似乎由于 useState 未更新它而访问不存在的属性导致此错误?

尽管我发出过与此非常相似的 GET 请求,但这是我第一次使用 useLocation()。我不确定这是否与问题有关,或者是否与 useState() 有关。

任何回复都非常感谢

const getQuiz = async () => {
        try{
            // These values were passed by the difficulty Component
            const categoryName = location.state?.name
            const difficulty = location.state?.difficulty

            // This makes a get request to get data for the quiz
            let response = await axios.get(`https://the-trivia-api.com/api/questions?categories=${categoryName}&limit=10&difficulty=${difficulty}`)
            let arrayDataResponse = await response.data

            // This sets the data to question array so that it is accessible outside of this function
            setQuestionArray(arrayDataResponse)

            // this outputs an empty array
            console.log(questionArray)

        } catch(err){
            console.log(err)
        }

    }

    // This fetches the data on mount
    useEffect(() => { getQuiz() }, [])

    // This will set the data for the elements once the state of the question array has been set from the get request
    useEffect(() => { 

        // This sets the content for the question element
        setQuestion(questionArray[0].question)
        // <h4>{question}</h4>

        // Uncaught TypeError: Cannot read properties of undefined (reading 'question')
    }, [questionArray])
2个回答

我猜你的状态是这样定义的...

const [questionArray, setQuestionArray] = useState([]);
const [question, setQuestion] = useState(/* some initial value */);

这意味着当你的组件初始化并挂载时, questionArray 是一个空数组。

Effect 钩子不仅在其依赖项更改时执行,而且在初始化时执行。这意味着当这个钩子第一次运行时...

useEffect(() => {
  setQuestion(questionArray[0].question);
}, [questionArray]);

它试图在 undefined 上访问 .question ,因此出现错误。


我会完全跳过 question 状态和上面的钩子。如果您想要某个东西来表示可选的第一个问题,您可以改用 memo hook

const firstQuestion = useMemo(() => questionArray[0]?.question, [questionArray]);

或者直接使用 questionArray[0]?.question ,而不使用任何钩子。

这将返回第一个 question 属性或 undefined ,您可以使用条件渲染来检测它。

{firstQuestion && (
  <p>{firstQuestion}</p>
)}
{/* or */}
{questionArray.length > 0 && (
  <p>{questionArray[0].question}</p>
)}
Phil
2022-08-10
357570445
Dot Simplify
2022-08-09