React组件中onClick触发时数组被清空的问题排查
问题描述
我有两个父div,每个父div下包含5个子div。点击子div时会调用修改类名的函数,双击子div时会调用从数组中弹出最后一个元素并推入指定值的函数。后续会基于两个数组的值执行条件判断,但当前问题是第一个数组传入条件判断时始终为空;若移除onClick相关代码,数组就能正常传入条件判断,请问该问题的原因是什么?
相关代码
import React, { Component, useEffect, useState } from "react"; const Survey = () => { const array1 = []; const array2 = []; const [classA, setClassA] = useState(); const handleClassA = (id) => { setClassA(id); } const handleArray1 = (id) => { array1.pop(); array1.push(id); console.log('array1', array1); } const [classB, setClassB] = useState(); const handleClassB = (id) => { setClassB(id); } const handleArray2 = (id) => { array2.pop(); array2.push(id); console.log('array2', array2); } const Quiz = () => { if (array1.includes(0) || array1.includes(1) || array1.includes(2)) { console.log('one is 0,1,2'); if (array2.includes(0) || array2.includes(1) || array2.includes(2)) { console.log('two is 0,1,2'); } else if (array2.includes(3) || array2.includes(4)) { console.log('counseling'); setResult("Counseling2"); } } else if (array1.includes(3) || array1.includes(4)) { console.log('one is 3,4'); if (array2.includes(0) || array2.includes(1) || array2.includes(2)) { console.log('two is 0, 1,2'); } } else if (array2.includes(3) || array2.includes(4)) { console.log('two is 3,4'); console.log('therapy'); setResult("Therapy") } console.log('quiz done'); console.log(array1); console.log(array2); } return( <div className="survey_questions"> <div className="survey_q_1"> <p id="q_1">I’m concerned about a behavior, feeling, or something I’m doing.</p> <div className="survey_a_1"> <div className={classA === 0 ? "survey_a_active" : "survey_a"} id="a_1" onClick={() => { handleClassA(0); }} onDoubleClick={() => { handleArray1(0) }} > not at all </div> <div className={classA === 1 ? "survey_a_active" : "survey_a"} id="a_1" onClick={() => { handleClassA(1); }} onDoubleClick={() => { handleArray1(1) }} > just a little </div> <div className={classA === 2 ? "survey_a_active" : "survey_a"} id="a_1" onClick={() => { handleClassA(2); }} onDoubleClick={() => { handleArray1(2) }} > moderately </div> <div className={classA === 3 ? "survey_a_active" : "survey_a"} id="a_1" onClick={() => { handleClassA(3); }} onDoubleClick={() => { handleArray1(3) }} > quite a lot </div> <div className={classA === 4 ? "survey_a_active" : "survey_a"} id="a_1" onClick={() => { handleClassA(4); }} onDoubleClick={() => { handleArray1(4) }} > very much </div> </div> </div > <div className="survey_q_1"> <p id="q_1">This behavior or feeling has been getting worse in the past few weeks.</p> <div className="survey_a_1"> <div className={classB === 5 ? "survey_a_active" : "survey_a"} id="a_1" onClick={() => { handleClassB(5); }} onDoubleClick={() => { handleArray2(0) }}> not at all </div> <div className={classB === 6 ? "survey_a_active" : "survey_a"} id="a_1" onClick={() => { handleClassB(6); }} onDoubleClick={() => { handleArray2(1) }}> just a little </div> <div className={classB === 7 ? "survey_a_active" : "survey_a"} id="a_1" onClick={() => { handleClassB(7); }} onDoubleClick={() => { handleArray2(2) }}> moderately </div> <div className={classB === 8 ? "survey_a_active" : "survey_a"} id="a_1" onClick={() => { handleClassB(8); }} onDoubleClick={() => { handleArray2(3) }}> quite a lot </div> <div className={classB === 9 ? "survey_a_active" : "survey_a"} id="a_1" onClick={() => { handleClassB(9); }} onDoubleClick={() => { handleArray2(4) }}> very much </div> </div> </div > </div> ) } export default Survey;
问题原因及解决方案
核心原因
- 普通变量无法在组件重渲染时保留状态:你定义的
array1和array2是组件函数内部的普通变量,不是React状态。当点击子div触发handleClassA并调用setClassA时,会触发组件重新渲染,此时array1 = []会被重新执行,之前双击添加的元素会被清空,所以后续条件判断里array1始终为空。 - 移除onClick后的逻辑:如果去掉onClick相关代码,
setClassA不会被调用,组件不会触发重渲染,array1的修改会保留在当前组件实例中,所以条件判断能读到正确的值。
修复方案
把array1和array2改成React状态,利用useState来管理,这样组件重渲染时状态值会被保留:
// 替换原有的普通数组定义 const [array1, setArray1] = useState([]); const [array2, setArray2] = useState([]); // 修改handleArray1和handleArray2函数 const handleArray1 = (id) => { setArray1(prevArray => { const newArray = [...prevArray]; newArray.pop(); newArray.push(id); return newArray; }); } const handleArray2 = (id) => { setArray2(prevArray => { const newArray = [...prevArray]; newArray.pop(); newArray.push(id); return newArray; }); }
另外注意:原代码中Quiz函数里使用了setResult但未定义result状态,需要补充const [result, setResult] = useState("");才能正常运行。
内容的提问来源于stack exchange,提问作者Noha derwa
相关产品推荐
相关产品推荐

