2017-11-16 20 views
0

私は自分のコンポーネントの状態を変更するためにsetStateを使用しています。状態が上書きされないようにしてください

状態から要素を削除する必要があるまでは正常に動作します。

はのは、私は私の店でこれを持っているふりをしてみましょう:

{ 
    0: {name: foo}, 
    1: {name: bar} 
} 

私は別の要素を追加した場合、それだけで正常に動作します:

store[2] = {name: hohoho}; 
setState(store, console.log(this.state)); 

上記のコードでは、私が期待される状態になってしまいます:

ただし、ストアから要素の1つを削除して状態を再度変更しても、削除されません

delete store[2] 

私は(ストア)にconsole.log場合は、私が手に:その後、

{ 
    0: {name: foo}, 
    1: {name: bar} 
} 

:状態から

setState(store, console.log(this.state)) 

は私を与える:

{ 
    0: {name: foo}, 
    1: {name: bar}, 
    2: {name: hohoho}, 
} 

しかし、それよりも見知らぬ人は、別の要素をストアに追加して、状態を設定した後です:

{ 
    0: {name: foo}, 
    1: {name: bar}, 
    2: {name: hohoho}, 
    3: {name: heyheyhey} 
} 

はconsole.log(店舗)は私に次のことを与えている場合でも:

{ 
    0: {name: foo}, 
    1: {name: bar}, 
    3: {name: heyheyhey} 
} 

誰かが起こっていただきました!私が理解する助けてくださいすることができ、私は次のような状態で終わる

store[3] = {name: heyheyhey}; 
setState(store, console.log(this.state)); 

に?

EDIT

いくつかのコメントを削除したので問題かもしれないが、私は私が私の店から削除しています方法変更:

var temp = {}; 
for (var x in store) { 
    if (x != id) { 
     temp[x] = store[x]; 
    } 
} 
store= temp; 

をしかし、私はまだ同じ問題を経験しています。

+0

毎回状態オブジェクトを変更する代わりに新しいオブジェクトを生成するたびに –

+0

新しいオブジェクトを作成することはどういう意味ですか?あなたは精緻化できますか? –

+0

それは、あなたが思うように、 'delete'はメモリを解放しないからです。 –

答えて

0

私のコメントで述べたような質問に答えるには。 Deleteは、キーワードのようにメモリを解放しないと思っています。

は共通の信念を示唆するものとは異なりMDN Delete

によると、delete演算子は、直接メモリを解放するとは何の関係もありません。メモリ管理は、参照を破棄して間接的に行われます。

古いものを変更するのではなく、新しいオブジェクトで置き換えるだけです。

編集:

は、私はあなたが誤って二setStateのparamを使用していると思う。この

cloneObject(obj) { 
     if (null == obj || "object" != typeof obj) return obj; 
     var copy = obj.constructor(); 
     for (var attr in obj) { 
      if (obj.hasOwnProperty(attr)) { 
       copy[attr] = obj[attr]; 
      } 
     } 
     return copy; 
} 
+0

それはまだ動作していません。更新されたコードで答えを更新しました。 –

+0

@RafaelAntunes '='で値を設定するだけでは、オブジェクトの新しいコピーがコピーされません。まだ参考になっています。 –

+0

@RafaelAntunesコードサンプルを –

1

のようなものを試してみてください。.. あなたがいることを認識しておく必要がありますし

SETSTATE()直ちにthis.stateを突然変異させるのではなく、保留中の状態遷移を作成します。このメソッドを呼び出した後this.stateにアクセスすると、潜在的に既存の値が返される可能性があります。

setStateの二番目のパラメータのコールバックである:また

は、SETSTATEが完了し、部品は再レンダリングされた後に実行されるオプションのコールバック関数を供給することができます。 だからあなたのコールバックのようなものでなければなりません。(そうしないとあなただけの現在のクラスの状態をログに記録し、第二のparamとしてundefinedを返すことだろう

setState(store, console.log) 

setState(store, (newState) => console.log(newState); 

またはそれの短いバージョンコールバック)

+0

もし私が別の要素を追加すると、前の要素を削除せずに別の要素が追加されているという部分を読んでください。 –

+1

私の答えをもう一度読んで、あなたは間違った方法でsetStateを使っています。コールバックに転送されたパラメータは、最終状態です。あなたは状態を設定する前に 'console.log'を呼び出しています.... – enapupe

0

削除の代わりにundefinedを使用することがあります。

const changes = [ 
    { 
    title: 'add 2', 
    update: state => Object.assign({}, state, { 2: { name: 'hohoho' } }), 
    }, 
    { 
    title: 'remove 2', 
    update: state => Object.assign({}, state, { 2: undefined }), 
    }, 
    { 
    title: 'add 3', 
    update: state => Object.assign({}, state, { 3: { name: 'heyheyhey' } }), 
    }, 
]; 

class App extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     0: { name: 'foo' }, 
     1: { name: 'bar' }, 
    }; 
    } 

    update(step) { 
    this.setState(changes[step].update); 
    } 

    componentDidMount() { 
    setTimeout(this.update.bind(this, 0), 2000); 
    setTimeout(this.update.bind(this, 1), 4000); 
    setTimeout(this.update.bind(this, 2), 6000); 
    } 

    render() { 
    return (
     <pre> 
     {JSON.stringify(this.state, null, 2)} 
     </pre> 
    ); 
    } 
} 

は、ここでそれを試してみてください:あなたがthis.setState({ a: something })を行うとhttps://jsfiddle.net/jprogd/062z1kqd/2/

はところで、あなたは実際に{ a: something }に正確に全体の状態を設定するだけで特定のプロパティを(この特定の場合にのみaプロパティが更新されます)更新されません。

関連する問題