我试图通过使用这样的嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态,
this.setState({ someProperty.flag: false });
是行不通的。怎样才能正确地做到这一点呢?
我试图通过使用这样的嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态,
this.setState({ someProperty.flag: false });
是行不通的。怎样才能正确地做到这一点呢?
当前回答
如果你想动态设置状态
下面的示例动态设置表单的状态,其中状态中的每个键都是object
onChange(e:React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) {
this.setState({ [e.target.name]: { ...this.state[e.target.name], value: e.target.value } });
}
其他回答
把它写在一行里
this.setState({ someProperty: { ...this.state.someProperty, flag: false} });
如果你在你的项目中使用formik,它有一些简单的方法来处理这些东西。下面是使用formik最简单的方法。
首先在formik initivalues属性或react中设置初始值。状态
这里,初始值是在react状态下定义的
state = {
data: {
fy: {
active: "N"
}
}
}
在formik initiValues属性中定义以上的initialValues字段
<Formik
initialValues={this.state.data}
onSubmit={(values, actions)=> {...your actions goes here}}
>
{({ isSubmitting }) => (
<Form>
<Field type="checkbox" name="fy.active" onChange={(e) => {
const value = e.target.checked;
if(value) setFieldValue('fy.active', 'Y')
else setFieldValue('fy.active', 'N')
}}/>
</Form>
)}
</Formik>
制作一个控制台来检查状态更新为字符串而不是布尔值formik setFieldValue函数来设置状态或使用react调试器工具来查看formik状态值的变化。
这样就足够了,
const isObject = (thing) => {
if(thing &&
typeof thing === 'object' &&
typeof thing !== null
&& !(Array.isArray(thing))
){
return true;
}
return false;
}
/*
Call with an array containing the path to the property you want to access
And the current component/redux state.
For example if we want to update `hello` within the following obj
const obj = {
somePrimitive:false,
someNestedObj:{
hello:1
}
}
we would do :
//clone the object
const cloned = clone(['someNestedObj','hello'],obj)
//Set the new value
cloned.someNestedObj.hello = 5;
*/
const clone = (arr, state) => {
let clonedObj = {...state}
const originalObj = clonedObj;
arr.forEach(property => {
if(!(property in clonedObj)){
throw new Error('State missing property')
}
if(isObject(clonedObj[property])){
clonedObj[property] = {...originalObj[property]};
clonedObj = clonedObj[property];
}
})
return originalObj;
}
const nestedObj = {
someProperty:true,
someNestedObj:{
someOtherProperty:true
}
}
const clonedObj = clone(['someProperty'], nestedObj);
console.log(clonedObj === nestedObj) //returns false
console.log(clonedObj.someProperty === nestedObj.someProperty) //returns true
console.log(clonedObj.someNestedObj === nestedObj.someNestedObj) //returns true
console.log()
const clonedObj2 = clone(['someProperty','someNestedObj','someOtherProperty'], nestedObj);
console.log(clonedObj2 === nestedObj) // returns false
console.log(clonedObj2.someNestedObj === nestedObj.someNestedObj) //returns false
//returns true (doesn't attempt to clone because its primitive type)
console.log(clonedObj2.someNestedObj.someOtherProperty === nestedObj.someNestedObj.someOtherProperty)
这是我的initialState
const initialStateInput = {
cabeceraFamilia: {
familia: '',
direccion: '',
telefonos: '',
email: ''
},
motivoConsulta: '',
fechaHora: '',
corresponsables: [],
}
钩子或者你可以用状态(类组件)替换它
const [infoAgendamiento, setInfoAgendamiento] = useState(initialStateInput);
handleChange的方法
const actualizarState = e => {
const nameObjects = e.target.name.split('.');
const newState = setStateNested(infoAgendamiento, nameObjects, e.target.value);
setInfoAgendamiento({...newState});
};
使用嵌套状态设置状态的方法
const setStateNested = (state, nameObjects, value) => {
let i = 0;
let operativeState = state;
if(nameObjects.length > 1){
for (i = 0; i < nameObjects.length - 1; i++) {
operativeState = operativeState[nameObjects[i]];
}
}
operativeState[nameObjects[i]] = value;
return state;
}
最后这是我使用的输入
<input type="text" className="form-control" name="cabeceraFamilia.direccion" placeholder="Dirección" defaultValue={infoAgendamiento.cabeceraFamilia.direccion} onChange={actualizarState} />
根据框架的标准,不确定这在技术上是否正确,但有时您只是需要更新嵌套对象。这是我使用钩子的解决方案。
setInputState ({ ... inputState, [括号]:内务部[括号],[childKey]: });