React中已初始化的state变量num为何显示undefined?
React State中
num变量显示undefined的问题解决 我在React组件中初始化了包含num:1的state对象,但页面渲染和控制台输出里state.num始终显示undefined,相关代码及控制台输出如下:
代码
import React, { useState} from "react"; import { ArrowCircleLeftIcon, StarIcon, XCircleIcon, PlusIcon} from "@heroicons/react/solid"; import AnswerBox from "./Test/Test"; function Test() { const [state, setState] = React.useState({ show: true, num:1, title: "", hide:false, }); return ( <div className="bg-white relative p-10 flex flex-row items-center align-middle shadow-2xl rounded-2xl"> <div className={ state.show ? "flex flex-col items-center align-middle" : "absolute scale-0 opacity-0 h-0 w-0" } > <h1 className="heading">Schedule Tests</h1> <select onChange={(e) => setState({ show: false, title: e.target.value })} className="h-12 text-xl p-2 border-black border-2" > <option>Select Class</option> <option>Demo class A</option> <option>Demo class B</option> <option>Demo class C</option> <option>Demo class D</option> </select> </div> <div className={ state.show ? "absolute scale-0 opacity-0 h-0 w-0" : "flex flex-col items-center align-middle p-3" } > <div className={state.hide ? "absolute scale-0 h-0 w-0 opacity-0":"absolute transition-all duration-150 origin-bottom text-4xl left-[-7rem] h-auto top-[-1rem] z-50 opacity-[.93] bg-blue-600 text-white rounded-lg shadow p-8"}> <div className="flex flex-col"> <div className="flex flex-row items-center m-auto"> <StarIcon className="h-[5rem] w-[5rem] rounded-full mr-2 bg-blue-400 text-yellow-400 rotate-[-12deg] shadow-2xl shadow-blue-800" /> <h1 className="text-[4rem]">Tips</h1> <XCircleIcon onClick={() => setState({...state,hide:true})} className="h-[4rem] w-[4rem] rounded-full text-red-400 hover:scale-110 hover:text-red-500 transition-all duration-200 origin-center cursor-pointer absolute right-0 top-0"/> </div> <div className="flex flex-row mb-6 mt-6"> <StarIcon className="h-12 w-12 rounded-full bg-blue-400 mr-2" /> How to put a Text Answer? </div> <div className="bg-blue-400 rounded p-1 px-2"> Write the answer on the first option box and tick it. </div> </div> </div> <ArrowCircleLeftIcon onClick={() => setState({ show: true, title: "" })} className="h-12 w-12 mb-4 top-0 hover:bg-red-600 rounded-full bg-red-400 shadow-2xl text-white cursor-pointer absolute left-0" /> {console.log(state.num)} <h1 className="heading mt-3">{state.title}</h1> Num: {state.num} </div> </div> ); } export default Test;
控制台输出
test.js:57 undefined
test.js:57 undefined
test.js:57 undefined
test.js:57 undefined
问题原因
你在两处调用setState时没有保留原state的所有属性:
- 下拉框的
onChange事件中,直接传入{ show: false, title: e.target.value },这会完全替换原state对象,导致num和hide属性丢失,新state中没有num,自然显示undefined。 - 返回按钮的
onClick事件中,同样只传入了show和title,丢弃了num和hide。
只有XCircleIcon的点击事件是正确的,它使用了扩展运算符...state复制原state的所有属性,再修改hide,所以不会丢失其他属性。
解决方法
每次调用setState时,先用扩展运算符...state复制原state的全部属性,再修改需要更新的字段,确保未修改的属性被保留:
- 修改下拉框的
onChange:
onChange={(e) => setState({ ...state, show: false, title: e.target.value })}
- 修改返回按钮的
onClick:
onClick={() => setState({ ...state, show: true, title: "" })}
这样修改后,num属性会一直保留在state中,页面和控制台就能正确显示1了。
内容的提问来源于stack exchange,提问作者soumya deep sarkar
相关产品推荐
相关产品推荐

