2017-12-28 11 views
1

그래서 React를 처음 사용했습니다. 함수 맵을 사용하여 Component 상태의 객체 배열에 ID를 제공하려고합니다. 그러나 함수의 객체를 반복 할 때 결과로 생성 된 배열의 요소는 모두 동일하며 마지막으로 반복 된 요소와 같습니다. 고유 ID를 추가하기 위해 uuid 모듈을 사용하고 있습니다. 이것은 내가 코멘트 안에 더 나은 설명과 함께 Component 내부에있는 것입니다 :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

'배열 #의 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 = classObject 
    obj.id = uuid.v4() 
    console.log(this.state.classes[0].id === this.state.classes[1].id) // true 
    return obj 
    }) 

당신은 결과를 원하는 얻을 수있는 개체를 돌연변이를 방지하고 새 개체 매번 작성해야합니다입니다

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 
    })