구성 요소 상태의 배열에서 요소를 제거하는 가장 좋은 방법을 찾으려고합니다. this.state
변수를 직접 수정해서는 안되므로 배열에서 요소를 제거하는 더 나은 방법 (더 간결한 방법)이 있습니까?
onRemovePerson: function(index) {
this.setState(prevState => { // pass callback in setState to avoid race condition
let newData = prevState.data.slice() //copy array from prevState
newData.splice(index, 1) // remove element
return {data: newData} // update state
})
},
감사합니다.
업데이트
setState에서 콜백을 사용하도록 업데이트되었습니다. 업데이트하는 동안 현재 상태를 참조 할 때 수행해야합니다.
답변
내가 본 가장 깨끗한 방법은 다음과 filter
같습니다.
removeItem(index) {
this.setState({
data: this.state.data.filter((_, i) => i !== index)
});
}
답변
에서 update()
불변성 도우미를react-addons-update
사용할 수 있습니다 .
this.setState(prevState => ({
data: update(prevState.data, {$splice: [[index, 1]]})
}))
답변
this.state
내부 참조 setState()
는 권장하지 않습니다 ( 상태 업데이트는 비동기 일 수 있음 ).
문서 setState()
는 업데이트가 발생할 때 prevState가 런타임에 전달되도록 콜백 함수와 함께 사용 하는 것이 좋습니다 . 이것이 다음과 같이 보입니다 :
ES6없이 Array.prototype.filter 사용
removeItem : function(index) {
this.setState(function(prevState){
return { data : prevState.data.filter(function(val, i) {
return i !== index;
})};
});
}
ES6 화살표 함수와 함께 Array.prototype.filter 사용
removeItem(index) {
this.setState((prevState) => ({
data: prevState.data.filter((_, i) => i !== index)
}));
}
불변 헬퍼 사용하기
import update from 'immutability-helper'
...
removeItem(index) {
this.setState((prevState) => ({
data: update(prevState.data, {$splice: [[index, 1]]})
}))
}
스프레드 사용
function removeItem(index) {
this.setState((prevState) => ({
data: [...prevState.data.slice(0,index), ...prevState.data.slice(index+1)]
}))
}
사용 된 기술에 관계없이 각각의 경우 에 이전에 대한 객체 참조가 아닌this.setState()
콜백이 전달 된다는 점에 유의하십시오 .this.state
답변
다음은 ES6 스프레드 구문을 사용하여 상태의 배열에서 요소를 제거하는 방법입니다.
onRemovePerson: (index) => {
const data = this.state.data;
this.setState({
data: [...data.slice(0,index), ...data.slice(index+1)]
});
}
답변
이 질문 에 @pscl 이 이미 올바르게 대답 했지만 다른 사람이 내가 한 것과 같은 문제가 발생하는 경우를 대비 하여 여기에 차임하고 싶습니다 . 4 가지 방법 중 나는 간결하고 외부 라이브러리에 대한 의존성이 없기 때문에 화살표 함수와 함께 es6 구문을 사용하기로 선택했습니다.
ES6 화살표 함수와 함께 Array.prototype.filter 사용
removeItem(index) {
this.setState((prevState) => ({
data: prevState.data.filter((_, i) => i != index)
}));
}
보시다시피 , 필자의 경우 문자열 필드에서 색인을 검색했기 때문에 색인 유형 ( !==
to !=
) 을 무시하도록 약간 수정했습니다 .
클라이언트 측에서 요소를 제거 할 때 이상한 동작이 나타나는 경우 또 다른 유용한 점 은 배열의 색인을 요소의 키로 사용하지 않는 것입니다 .
// bad
{content.map((content, index) =>
<p key={index}>{content.Content}</p>
)}
React가 변경 사항에서 가상 DOM과 차이점을 변경하면 변경된 내용을 결정하는 키를 살펴 봅니다. 따라서 인덱스를 사용하고 있고 배열에 적은 것이 있으면 마지막 인덱스를 제거합니다. 대신 콘텐츠의 ID를 키로 사용하십시오.
// good
{content.map(content =>
<p key={content.id}>{content.Content}</p>
)}
위의 내용은 관련 게시물의 답변에서 발췌 한 것입니다 .
모두 행복한 코딩!
답변
색인없이 요소를 제거하려는 경우이 기능을 사용할 수 있습니다.
removeItem(item) {
this.setState(prevState => {
data: prevState.data.filter(i => i !== item)
});
}
답변
위의 ephrion의 답변에 대한 언급에서 언급했듯이 filter ()는 이미 큰 것으로 판단되는 인덱스를 찾기 위해 반복되므로 특히 큰 배열의 경우 느릴 수 있습니다. 이것은 깨끗하지만 비효율적 인 솔루션입니다.
대안으로서, 원하는 요소를 간단히 ‘슬라이스’하고 단편들을 연결할 수있다.
var dummyArray = [];
this.setState({data: dummyArray.concat(this.state.data.slice(0, index), this.state.data.slice(index))})
도움이 되었기를 바랍니다!