如何解决默认下拉列表值仅在初始输入后呈现
我有一个带有下拉菜单的输入表单,我试图设置一个默认值。该值从父组件传递下来,并从异步函数(我认为可能有一部分)接收。异步功能将用户名呈现在h1中,并正确显示在表单上方。它还充当根据一个人的名字确定默认值的条件。我尝试在多个组件中使用状态,并且总是以“错误:重新渲染过多。 React限制了渲染次数以防止无限循环。”请在下面查看并帮助我解决问题,如果您可以在此提供一些我缺少的概念的主题,将不胜感激。
const dashboard = (props)=>{
const getName = async ()=>{
try{~GETS DATA~
setName(parsedData[0].user_name}
catch{error}
}
let defaultSchool
//switch statement chooses the value for the default in dropdown menu based on the name from GET
switch(name){
case "user1":
defaultSchool= "Cool School"
case "user2":
defaultSchool= "Another School
}
return(
<div>
<InputForm defaultSchool= defaultSchool />
</div>
)
}
上面是父组件,它将这些数据向下传递到包含输入表单的下一个组件。
const InputForm = ({defaultSchool})=>{
const [school,setSchool]= useState(defaultSchool)
const [some_state,setSome_State] = useState("")
// numerous other states associated with the form with no significant relevance
const onSubmitForm = async e => {
e.preventDefault()
try{~normally POSTS data~}
catch{error}
}
return(
<h1 className="text-center my-5 input
title">Input Form</h1>
<form className="mt-5" onSubmit={onSubmitForm}>
{/* DATE */}
<input type="date" name="connection_date"
placeholder="Date of Contact"
className="form-control"
value={connection_date}
onChange={e => setDate(e.target.value)}/>
{/* SCHOOL */}
<select type="text" name="school"
placeholder="School" className="form-control mt-3"
defaultValue={defaultSchool} value={defaultSchool}
onChange={e => setSchool(e.target.value)}>
// <option value="NADA" disabled>Choose your school</option>
// this is a default option i tried with defaultValue to stop the first
value in the dropdown from showing which was unsuccessful also
to show but didn't work at all either
<option value="Cool School"> Cool School </option>
<option value="Another School">Another School </option>
<button className="btn btn-success btn-block mt-3 mb-5">Add</button>
</form>
)
}
最初,默认学校在下拉列表中显示为选定项目;我单击添加按钮,但学校尚未提交。但是,在第一次单击“添加”按钮后,将发生正确的行为,并且每增加一次单击,都将提交学校。有很多关于此问题的SO帖子,但都没有包含React和hooks或提供有条件的呈现下拉列表默认选项的任何见解。
完整的代码示例:
import React,{ Fragment,useState,useEffect } from 'react'
//components
import InputConnection from './connectionlist/InputConnection'
import ListConnections from './connectionlist/ListConnections'
import LogoutBtn from './LogoutBtn'
import ReportingLayout from './reporting/Layout/ReportingLayout'
const Dashboard = ({ setAuth }) => {
const [name,setName] = useState("")
const [allConnections,setAllConnections] = useState([])
const [connectionsChange,setConnectionsChange] = useState(false)
const [timeDay,setTimeDay] = useState("Good Morning,")
const auth = setAuth
const getName = async () => {
try {
const response = await fetch("/dashboard/",{
method:"GET",headers:{ token: localStorage.token }
})
const parseData = await response.json()
// console.log(parseData)
if (parseData.admin === 'lead') {
setName("Lead School Counselor")
setAllConnections(parseData.results)
}else{
setName(parseData[0].user_name)
setAllConnections(parseData)
}
} catch (error) {
}
}
const greeting = () => {
let date = new Date()
const hours = date.getHours()
if(hours < 12){
setTimeDay("Good Morning,")
}else if (hours >= 12 && hours < 17){
setTimeDay("Good Afternoon,")
}else{
setTimeDay("Good Evening,")
}
}
useEffect(() => {
getName()
greeting()
setConnectionsChange(false)
},[connectionsChange,timeDay])
if(name === "Lead School Counselor" ){
return(
<div>
<ReportingLayout auth={auth} allConnections={ allConnections } />
</div>
)
}else{
let defaultSchool
switch(name) {
case 'Jim Smith':
defaultSchool= "Cool School"
break;
case "Bob Williams":
defaultSchool= "Another School"
break;
}
return(
<Fragment>
<div className="container">
<div className='btn-group '>
<LogoutBtn setAuth = {setAuth}/>
</div>
<h1 className="d-flex mt-3 pl-3" > {timeDay}
{name} </h1>
<InputConnection defaultSchool={defaultSchool}
setConnectionsChange={setConnectionsChange}/>
<ListConnections allConnections={ allConnections }
setConnectionsChange={setConnectionsChange}/>
</div>
</Fragment>
)
}
}
导出默认仪表板;
下一个组件:
import React,useState } from "react";
import { toast } from 'react-toastify'
const InputTodo = ({ defaultSchool,setConnectionsChange }) => {
const today = new Date()
var formattedDate = today.toISOString().substr(0,10);
const [contact_type,setContactType] = useState("");
const [contact_method,setContactMethod] = useState("");
const [provision,setProvision] = useState("");
const [connection_date,setDate] = useState(formattedDate);
const [student_id,setStudentID] = useState("");
const [purpose,setPurpose] = useState("");
const [gender,setGender] = useState("");
const [yearGroup,setYearGroup] = useState("");
const [referral_discharge,setReferralDischarge] = useState("");
const [cp_referral,setCPReferral] = useState("");
const [school,setSchool] = useState(defaultSchool);
const onSubmitForm = async e => {
e.preventDefault();
try {
const myHeaders = new Headers();
myHeaders.append("Content-Type","application/json");
myHeaders.append("token",localStorage.token);
const body = {
contact_type,contact_method,provision,connection_date,student_id,purpose,gender,yearGroup,school,referral_discharge,cp_referral
};
const response = await fetch("/dashboard/connections",{
method: "POST",headers: myHeaders,body: JSON.stringify(body)
});
const parseResponse = await response.json();
console.count(parseResponse);
setConnectionsChange(true);
setContactType("")
setContactMethod("")
setProvision("")
setDate(formattedDate)
setStudentID("")
setPurpose("")
setGender("")
setYearGroup("")
setSchool(defaultSchool)
setReferralDischarge("")
setCPReferral("")
toast.success('Contact has been added',{
position: "top-center",autoClose: 3000,hideProgressBar: false,closeOnClick: true,pauseOnHover: true,draggable: true,});
} catch (error) {
console.error(error.message);
}
};
return (
<Fragment>
<h1 className="text-center my-5 input-title">Communication Log</h1>
<form className="mt-5" onSubmit={onSubmitForm}>
{/* DATE */}
<input type="date" name="connection_date" placeholder="Date of Contact"
className="form-control" value={connection_date} onChange={e =>
setDate(e.target.value)}/>
{/* SCHOOL */}
<select type="text" name="school" placeholder="School" className="form-
control mt-3" defaultValue={defaultSchool} value={defaultSchool}
onChange={e => setSchool(e.target.value)}>
<option value="NADA" disabled>Choose your school</option>
<optgroup label= "SEN">
<option value="Cool School">Cool SChool</option>
<option value= "Another School">Another School</option>
</optgroup>
</select>
{/* SCHOOL ID */}
<input type="text" name="student_id" placeholder="Student ID"
className="form-control mt-3" value={student_id} onChange={e =>
setStudentID(e.target.value)}/>
{/* YEAR / GROUP */}
<select type="text" name="yeargroup" placeholder="year/group"
className="form-control mt-3" value={yearGroup} onChange={e =>
setYearGroup(e.target.value)}>
<option value="DEFAULT">Choose the Year/ Group</option>
<option value="yr01">yr01</option>
<option value="yr02">yr02</option>
<option value="yr03">yr03</option>
<option value="yr04">yr04</option>
<option value="yr05">yr05</option>
<option value="yr06">yr06</option>
<option value="yr07">yr07</option>
<option value="yr08">yr08</option>
<option value="yr09">yr09</option>
<option value="yr10">yr10</option>
<option value="yr11">yr11</option>
<option value="yr12">yr12</option>
</select>
{/* GENDER */}
<select type="text" name="gender" placeholder="gender" className="form-control mt-3" value={gender} onChange={e => setGender(e.target.value)}>
<option value="DEFAULT">Gender</option>
<option value="M">M</option>
<option value="F">F</option>
</select>
{/* REFERRAL OR DISCHARGE */}
<select type="text" name="referral_discharge" placeholder="referral_discharge" className="form-control mt-3" value={referral_discharge} onChange={e => setReferralDischarge(e.target.value)}>
<option value="DEFAULT">Was this a referral,continuation or discharge?</option>
<option value="referral">Referral</option>
<option value="discharge">Discharge</option>
<option value="continuation">Continuation</option>
</select>
{/* CONTACT TYPE */}
<select type="text" name="contact_type" placeholder="contact_type" className="form-control mt-3" value={contact_type} onChange={e => setContactType(e.target.value)}>
<option value="DEFAULT">Type of Contact</option>
<option value="student">student</option>
<option value="parent">parent</option>
<option value="emergeny contact">emergeny contact</option>
<option value="staff">staff</option>
<option value="social worker">social worker</option>
<option value="support staff">support staff</option>
<option value="SENCO">SENCO</option>
<option value="other">other</option>
</select>
{/* CONTACT METHOD */}
<select type="text" name="contact_method" placeholder="contact_method" className="form-control mt-3" value={contact_method} onChange={e => setContactMethod(e.target.value)}>
<option value ="DEFAULT">Contact Mode/ Method</option>
<option value="in-person">in-person</option>
<option value="text">text</option>
<option value="whatsapp">whatsapp</option>
<option value="phone call">phone call</option>
<option value="email">email</option>
<option value="check-in">check-in</option>
<option value="classroom presentation">classroom presentation</option>
<option value="session">session</option>
<option value="video chat">video chat</option>
<option value="group">group session</option>
<option value="crisis intervention">crisis intervention</option>
<option value="home visit">home visit</option>
<option value="sbst,mdt,case conference">sbst,case conference</option>
<option value="outside agency meeting">outside agency meeting</option>
<option value="other meeting">other meeting</option>
</select>
{/* CP_REFERRAL */}
<select type="text" name="cp_referral" placeholder="cp_referral" className="form-control mt-3" value={cp_referral} onChange={e => setCPReferral(e.target.value)}>
<option value="DEFAULT">Was this a CP Referral?</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
{/* <div className='mt-3'>
<p>Is this a CP REFERRAL?</p>
<div className="form-check-inline">
<input className="form-check-input" type="radio" name="cp_referral" id="y" value={cp_referral} onClick={(e)=> setCp_referral(e.target.value)}/>
<label className="form-check-label">Yes</label>
</div>
<div className="form-check-inline">
<input className="form-check-input" type="radio" name="cp_referral" id="n" value={cp_referral} onClick={(e)=> setCp_referral(e.target.value)}/>
<label className="form-check-label">No</label>
</div>
</div> */}
{/* PURPOSE */}
<textarea className="form-control mt-3" name="purpose" placeholder="What was the purpose of the connection?" value={purpose} onChange={e => setPurpose(e.target.value)}></textarea>
{/* PROVISION */}
<textarea className="form-control mt-3" name="provision" placeholder="Provision/Support Agreed Upon/ Plan Forward (When Necessary) / Any Additional Notes" value={provision} onChange={e => setProvision(e.target.value)}></textarea>
{/* BUTTON */}
<button className="btn btn-success btn-block mt-3 mb-5">Add</button>
</form>
</Fragment>
); };
导出默认的InputTodo;
解决方法
我以前在下拉菜单中曾手动设置value
道具时遇到过此问题。发生的事情是,无论如何,下拉菜单中始终会有一个可见的选项。如果传入value
,则应显示该值。但是,如果您传递undefined
,则列表中的第一个选项将成为可见的选项。看起来 该选项已被选中,但实际上并未被选中。这就是为什么如果您选择另一个选项然后返回到第一个选项,它将起作用的原因,因为您实际上已经选择了它。
const [school,setSchool] = useState(defaultSchool)
useState
的初始状态仅设置一次。它不会响应您的defaultSchool
道具中的更改。因此,如果它首先接收到undefined
的值,那么school
将保持undefined
直到您调用setSchool
为止,即使稍后获得defaultSchool
的有效值也是如此
解决此问题的一种方法是使用useEffect
钩子监听对defaultSchool的更改。
useEffect( () => {
if ( defaultSchool & ! school ) {
setSchool( defaultSchool );
}
},[defaultSchool,school]);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。