2017-12-28 12 views
1

したがって、私はReactを初めて使用しています。私は関数マップを使用して、コンポーネントの状態でオブジェクトの配列にIDを渡そうとしています。しかし、関数内のオブジェクトを反復処理すると、結果として得られる配列の要素はすべて同じになり、最後に反復されたものと等しくなります。私はユニークなIDを追加するためにuuidモジュールを使用しています。これは、コンポーネントの内部にコメントの説明が含まれています。Reactのマップを使用すると、最後の要素に等しい配列が返されます

constructor() { 
    super() 
    this.state = { 
    classes: Array(5).fill({ 
     id: null, 
     name: null 
    }), 
    } 
} 

componentWillMount() { 

    // This console.log, strangely, logs the state of the Component as if 
    // this componentWillMount function had already been executed, showing the 
    // classes with their ids (still the wrong ones). Would appreciate it if 
    // someone explained that 
    console.log(this.state.classes) 

    let classThings = this.state.classes.map(classObject => { 
    let obj = classObject 
    obj.id = uuid.v4() 
    // This logs the object correctly. The console shows, thanks to this, 
    // five different objects with five different ids 
    console.log(obj) 
    return obj 
    }) 

    this.setState({ 
    classes: classThings 
    }) 

    // But, for some reason, this one logs the array and all the elements 
    // inside are equal to te last one logged by the previous console.log 
    // that is inside the map function, when it should log an array with the 
    // five different elements 
    console.log(classThings) 
} 

ご協力いただければ幸いです。ありがとう。

+0

を取得するために、新しいオブジェクト毎回作成する必要があり、すべての反復

let classThings = this.state.classes.map(classObject => { let obj = classObject obj.id = uuid.v4() console.log(this.state.classes[0].id === this.state.classes[1].id) // true return obj }) 

'アレイ#1 fill'は同じに、アレイ内のすべての要素を設定されていますオブジェクトであるため、最も最近の変更はオブジェクトに含まれるものになります。 – 4castle

+0

@ 4castleは応答に感謝します。しかし、私はコンストラクタで一度しか使用していませんが、setStateを使用してそれらのすべてが等しくない場合でも影響します。 –

答えて

1

同じオブジェクトへのあなたの配列classesポイント内のすべての要素(Array.fillはちょうどあなたがそれを渡された単一のオブジェクトに配列のすべての要素を設定するため)、あなたがclasses内の任意のオブジェクトに変更を加えるときに、あなたが変更していますすべてのオブジェクトはclassesです。あなたが代わりに各要素の新しいオブジェクトを作成するためにmapを使用することができます。

は、この変更に伴い

Array(5).fill(null).map(() => ({ 
    id: null, 
    name: null 
})) 

Array(5).fill({ 
    id: null, 
    name: null 
}) 

を交換し、あなたもclasses一意のID内の各オブジェクトを与えることができますcomponentWillMountの代わりに作成します。

Array(5).fill(null).map(() => ({ 
    id: uuid.v4(), 
    name: null 
})) 
+0

これは、感謝しました! –

0

すべての要素はthis.state.classesで同じです。それは

this.state.classes[0] === this.state.classes[1] // true 

を意味し、あなたがmap内の配列のオブジェクトを変異されているので、彼らはすべての点から、その変更は、最終的には同じオブジェクトを配列のすべての要素に反映されています。それmeanseはあなたがオブジェクトを変異避け、望ましい結果

let classThings = this.state.classes.map(classObject => { 
    let obj = Object.assign({}, classObject) 
    obj.id = uuid.v4() 
    console.log(this.state.classes[0].id === this.state.classes[1].id) // true 
    return obj 
    }) 
関連する問題