我已经在谷歌上搜索了这个问题的所有答案,但我自己仍然找不到答案。
我有一个包含bdate字符串和会话数组的父状态,这些元素的值来自子组件中的输入字段和复选框。我的代码的场景是,我取bdate并直接更改父状态中的值,然后取选中的元素并将它们放在子状态数组中,然后将数组作为参数传递给一个函数,该函数将数组分配给父组件中的会话数组。
问题是复选框的输入具有静态值,bdate的输入具有动态值。这种差异会产生一个错误,即"组件正在将受控输入更改为不受控输入",由于这个错误,即使我在中输入了一些输入,验证功能也会将bdate字段计数为空
如果有人需要更多信息,请提供更多解释:
我有一个包含对象的父状态,其中一个对象是一个名为会话的数组,会话数组应该从子组件复选框元素中获取其元素。我在生成代码时遵循的场景是,我在子组件中创建了一个单独的状态,该状态保存了选中元素的所有值,然后我需要用子组件中的数组更新父会话数组。这就是为什么我在父组件中创建了一个带有参数的函数,然后将该参数分配给会话,我将该函数作为道具传递给子组件,但每当我调用它时,我都会收到一个错误,即"组件正在将受控输入更改为不受控输入"!!!问题是,这个错误使浏览器将输入字段计数为空,并且验证会给出一个错误,这就是为什么不能根据useEffect中的条件提交表单的原因。
我知道这与value属性有关,但我不知道如何修复它。
这是我的父组件的代码
import react, { Component, useState } from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import AdminUser from './components/pages/adminUser';
import ProfileClient from './components/profileClient/profileC';
const App = () => {
//client data
const intialValuesClient = { bdate: "",session: [] };
//client state
const [clientValues, setClientValues] = useState(intialValuesClient);
//client handlechange function
const handleChangeClient = (e) => {
console.log(e.target.value);
const { name, value } = e.target;
setClientValues({ ...clientValues, [name]: value });
}
//update the session array
const setStateOfParent = (newSession) => {
setClientValues({
session: newSession
});
}
return (
<BrowserRouter>
<Routes>
<Route path='/' element={<AdminUser />} />
<Route path='/profileclient' element={<profileClient data={clientValues} change={handleChangeClient} setSession={setStateOfParent} />} />
</Routes>
</BrowserRouter>
)
}
export default App;
子组件代码
import react, { Component, useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import './profileC.css';
const ProfileC = (props) => {
const navigate = useNavigate();
const [profileErrors, setProfileErrors] = useState({});
const [isSubmit, setIsSubmit] = useState(false);
const [sessionSelected, setSessionSelected] = useState([]);
//function to push the checked elements into the state
const handleSession = (e) => {
// Destructuring
const { value, checked } = e.target;
console.log(`${value} is ${checked}`);
// Case 1 : The user checks the box
if (checked) {
setSessionSelected([...sessionSelected, value]);
}
// Case 2 : The user unchecks the box
else {
setSessionSelected({
sessionSelected: sessionSelected.filter((e) => e !== value)
});
}
};
const handleSubmit = (err) => {
err.preventDefault();
setProfileErrors(validate(props.data));
setIsSubmit(true);
}
useEffect(() => {
if (Object.keys(profileErrors).length === 0 && isSubmit) {
if (isSubmit) {
return (navigate('/verifyc'))
}
}
}, [profileErrors])
const validate = (values) => {
const errors = {};
if (!values.bdate) {
errors.bdate = 'bdate is required!';
}
return errors;
}
var show = true;
const showCheckboxes = () => {
var checkboxes =
document.getElementById("checkBoxes");
if (show) {
checkboxes.style.display = "block";
show = false;
} else {
checkboxes.style.display = "none";
show = true;
}
}
//here is where the error happens
const handleClick = () => {
// Simply call the setStateOfParent function from
// prop and pass required argument
props.setSession(sessionSelected);
}
return (
<div className="main">
<form onSubmit={handleSubmit} >
<div className="m_container">
<h1>Profile</h1>
<div className="m_birthday">
<input
type="date"
id="m_date"
name="bdate"
placeholder='Date of birth'
value={props.data.bdate}
onChange={props.change}
/>
</div>
<div className="multipleSelection">
<p className="selectBox" onClick={showCheckboxes}>What kind of session are you interested in?</p>
<div id="checkBoxes">
<label htmlFor='Individual Session'>Individual Session</label>
<input value='Individual Session' onChange={handleSession} onClick={handleClick} id='Individual Session' type="checkbox" name='session' />
<label htmlFor='Couples Session'>Couples Session</label>
<input value='Couple Session' onChange={handleSession} onClick={handleClick} id='Couples Session' type="checkbox" name='session' />
<label htmlFor='Family Session'>FamilySession</label>
<input value='Family Session' onChange={handleSession} onClick={handleClick} id='Family Session' type="checkbox" name='session' />
<label htmlFor='Group Session'>Group Session</label>
<input value='Group Session' onChange={handleSession} onClick={handleClick} id='Group Session' type="checkbox" name='session' />
<label htmlFor='Work Pressure Session'>Work Pressure Session</label>
<input value='Work Pressure Session' onChange={handleSession} onClick={handleClick} id='Work Pressure Session' type="checkbox" name='session' />
<label htmlFor='Teen Session'>Teen Session</label>
<input value='Teen Sesion' onChange={handleSession} onClick={handleClick} id='Teen Session' type="checkbox" name='session' />
</div>
</div>
<p className='errorMsg'>{profileErrors.session}</p>
<br />
<div className="m_clearfix">
<button type="submit" className="m_start">Start Your Journy</button>
</div>
</div>
</form>
</div>
</div>
</div>
)
}
export default ProfileC;
您应该传递一个数组作为参数,以防用户取消选中框,尝试更改handleSession
函数,如下所示:
const handleSession = (e) => {
// Destructuring
const { value, checked } = e.target;
console.log(`${value} is ${checked}`);
// Case 1 : The user checks the box
if (checked) {
setSessionSelected([...sessionSelected, value]);
}
// Case 2 : The user unchecks the box
else {
// Change this condition
const session = sessionSelected.filter((e) => e !== value);
setSessionSelected(session);
}
};