SETSTATEでオブジェクトのプロパティを更新するために、すべてのことは可能ですか?
何かのようなもの:
this.state = {
jasper: { name: 'jasper', age: 28 },
}
私が試してみました:
this.setState({jasper.name : 'someOtherName'});
この:
this.setState({jasper:{name:'someothername'}})
最初は構文エラーで、2番目はちょうど何もしません。何か案は?
これを行うための複数の方法があります。
1-最も簡単な1:
まず、その内の変更を行うjasper
のコピーを作成します。
let jasper = Object.assign({}, this.state.jasper); //creating copy of object
jasper.name = 'someothername'; //updating value
this.setState({jasper});
Object.assign
を使う代わりに、このように書くこともできます。
let jasper = {...this.state.jasper};
2-使用 拡散演算子:
this.setState(prevState => ({
jasper: {
...prevState.jasper,
name: 'something'
}
}))
最速かつ最も読みやすい方法:
this.setState({...this.state.jasper, name: 'someothername'});
this.state.jasper
にはすでにnameプロパティが含まれていますが、後者のname: 'someothername'
を使用してください。
ここでスプレッド演算子とES6を使用する
this.setState({
jasper: {
...this.state.jasper,
name: 'something'
}
})
私はこの解決策を使いました。
あなたがこのような入れ子になった状態があるならば:
this.state = {
formInputs:{
friendName:{
value:'',
isValid:false,
errorMsg:''
},
friendEmail:{
value:'',
isValid:false,
errorMsg:''
}
}
現在のステータスをコピーして値を変更して再割り当てするhandleChange関数を宣言できます。
handleChange(el) {
let inputName = el.target.name;
let inputValue = el.target.value;
let statusCopy = Object.assign({}, this.state);
statusCopy.formInputs[inputName].value = inputValue;
this.setState(statusCopy);
}
ここではイベントリスナーのHTMLです。状態オブジェクトに使用されているのと同じ名前(この場合は「friendName」)を必ず使用してください
<input type="text" onChange={this.handleChange} " name="friendName" />
これを試してください、それはうまく動作するはずです
this.setState(Object.assign(this.state.jasper,{name:'someOtherName'}));
最初のケースは確かに構文エラーです。
私はあなたのコンポーネントの残りを見ることができないので、あなたがここにあなたの状態でオブジェクトを入れ子にしている理由を見るのは難しいです。オブジェクトをコンポーネント状態でネストするのはお勧めできません。初期状態を次のように設定してみてください。
this.state = {
name: 'jasper',
age: 28
}
そのようにして、名前を更新したい場合は、単に呼び出すことができます。
this.setState({
name: 'Sean'
});
それはあなたが目指していることを達成するでしょうか?
大規模で複雑なデータストアには、Reduxのようなものを使用します。しかし、それははるかに進んでいます。
コンポーネントの状態に関する一般的な規則は、コンポーネントのUI状態を管理するためだけにそれを使用することです(例えば、active、timerなど)。
これらの参考文献をチェックしてください。
また、すべての "state"オブジェクトをコピーしたくない場合は、Alberto Pirasの解決法に従ってください。
handleChange(el) {
let inputName = el.target.name;
let inputValue = el.target.value;
let jasperCopy = Object.assign({}, this.state.jasper);
jasperCopy[inputName].name = inputValue;
this.setState({jasper: jasperCopy});
}
シンプルでダイナミックな方法.
これは仕事をしますが、親がオブジェクトの名前を指すようにすべてのIDを親に設定する必要があります。id = "jasper"で、入力要素の名前を=オブジェクトjasperの内側に設定します。 。
handleChangeObj = ({target: { id , name , value}}) => this.setState({ [id]: { ...this.state[id] , [name]: value } });
これで試すことができます :( 注 :入力タグの名前===オブジェクトのフィールド)
<input name="myField" type="text"
value={this.state.myObject.myField}
onChange={this.handleChangeInpForm}></input>
-----------------------------------------------------------
handleChangeInpForm = (e) => {
let newObject = this.state.myObject;
newObject[e.target.name] = e.target.value;
this.setState({
myObject: newObject
})
}
これは私のhandleInputChange関数です。あらゆる種類のオブジェクトに対して一般的な方法で機能します。しかし
evalの使用は強くお勧めできません
handleInputChange(event) {
const target = event.target;
const targetPropertyName = target.name.substr(target.name.indexOf('.'));
const targetObjectName = target.name.substr(0, target.name.indexOf('.'));
const value = target.value;
var obj = this.state[targetObjectName];
eval('obj' + targetPropertyName + '= value');
this.setState({
[targetObjectName]: obj
});
}
そして私の入力フォーム
<input id="inputEmail" type="email" value={this.state.user.email} name="user.email" onChange={this.handleInputChange}/>
Eval関数に代わるアイデアはありますか?
これで試すことができます:
this.setState(prevState => {
prevState = JSON.parse(JSON.stringify(this.state.jasper));
prevState.name = 'someOtherName';
return {jasper: prevState}
})
または他の財産の場合:
this.setState(prevState => {
prevState = JSON.parse(JSON.stringify(this.state.jasper));
prevState.age = 'someOtherAge';
return {jasper: prevState}
})
あるいはhandleChage関数を使うこともできます。
handleChage(event) {
const {name, value} = event.target;
this.setState(prevState => {
prevState = JSON.parse(JSON.stringify(this.state.jasper));
prevState[name] = value;
return {jasper: prevState}
})
}
とHTMLコード:
<input
type={"text"}
name={"name"}
value={this.state.jasper.name}
onChange={this.handleChange}
/>
<br/>
<input
type={"text"}
name={"age"}
value={this.state.jasper.age}
onChange={this.handleChange}
/>
もう1つの選択肢は、 Jasper オブジェクトから変数を定義してから、変数を呼び出すだけです。
拡散演算子:ES6
this.state = { jasper: { name: 'jasper', age: 28 } }
let foo = "something that needs to be saved into state"
this.setState(prevState => ({
jasper: {
...jasper.entity,
foo
}
})
非同期を使用せずに待つこれを使用する...
funCall(){
this.setState({...this.state.jasper, name: 'someothername'});
}
あなたがAsync And Awaitで使っているならこれを使ってください /
async funCall(){
await this.setState({...this.state.jasper, name: 'someothername'});
}