상태 배열로 푸시하는 올바른 방법


122

데이터를 상태 배열로 푸시하는 데 문제가있는 것 같습니다. 나는 이런 식으로 그것을 달성하려고합니다.

this.setState({ myArray: this.state.myArray.push('new value') })

그러나 이것이 잘못된 방법이라고 생각하며 변경 가능성에 문제가 있습니까?

답변:


145

배열 푸시 반환 길이

this.state.myArray.push('new value')배열 자체 대신 확장 배열의 길이를 반환합니다. Array.prototype.push () .

반환 값이 배열이 될 것으로 예상합니다.

불변성

오히려 React의 동작 인 것 같습니다.

나중에 setState ()를 호출하면 만든 변형을 대체 할 수 있으므로 this.state를 직접 변형하지 마십시오. this.state를 변경 불가능한 것처럼 취급하십시오. React.Component .

나는 다음과 같이 할 것이라고 생각합니다 (React에 익숙하지 않음).

var joined = this.state.myArray.concat('new value');
this.setState({ myArray: joined })

1
내가 할 때 console.log(this.state.myArray)항상 뒤에 하나입니다. 왜 그런지 아세요?
Si8

@ Si8 글쎄, 불행히도 React를 너무 많이 사용하지 않습니다. 그러나 문서는 다음과 같이 말합니다 : setState()구성 요소 상태의 변경 사항을 대기열에 추가하고 React에이 구성 요소와 그 자식을 업데이트 된 상태로 다시 렌더링해야한다고 알려줍니다. 그래서 설정 직후에는 업데이트되지 않은 것 같습니다. 설정하고 기록하고있는 지점을 볼 수있는 코드 예제를 게시 해 주시겠습니까?
Márton Tamás 19

응답 해 주셔서 감사합니다. 비동기식이므로 변경 사항을 즉시 표시하지 않습니다. 그러나 setState에는 올바른 값을 표시하는 콜백이 있습니다. 다시 한 번 감사드립니다.
Si8

w3schools.com/jsref/jsref_concat_array.asp.concat('new value');.concat(['new value']);
concatnates

1
@ManoharReddyPoreddy 배열이 아닌 값은 concat()메서드에 완벽하게 유효합니다 . 참조 : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ( 새 배열로 연결할 배열 및 / 또는 값. )
Márton Tamás

176

es6를 사용하면 다음과 같이 할 수 있습니다.

this.setState({ myArray: [...this.state.myArray, 'new value'] }) //simple value
this.setState({ myArray: [...this.state.myArray, ...[1,2,3] ] }) //another array

확산 구문


1
나는 똑같이했다. myArray가 값을 가질 수 있고 그렇지 않을 수있는 두 가지 경우가있다. 따라서 이미 값이 있으면 완벽하게 작동합니다. 그러나 데이터가 없습니다. '새 값'으로 상태를 업데이트하지 않습니다. 어떤 해결책이라도?
Krina Soni

모든 배열과 함께 작동해야하며 값이 있는지 여부에 관계없이 어쨌든 구조화되지 않습니다. 다른 곳에 뭔가 잘못되었을 수도 있습니다. 코드의 예를 보여 주시겠습니까?
Aliaksandr Sushkevich

안녕하세요 @Tamas 답변에서 내 의견을 참조하십시오. 콘솔의 샘플 일뿐입니다. 내 상태 배열을 업데이트하기 위해 myArray : [... this.state.myArray, 'new value']를 시도했습니다.하지만 마지막 값만 연결합니다. 해결책을 알려주시겠습니까?
Johncy

@Johncy 귀하의 문제가이 질문과 관련이 있는지 잘 모르겠습니다. 별도의 질문을하고 예상되는 동작을 설명해 주시면 도와 드리겠습니다.
Aliaksandr

5
당 문서 반응 : "때문에 this.propsthis.state비동기 적으로 업데이트 될 수 있습니다, 당신은 다음 상태를 계산하기 위해 그 값에 의존해서는 안됩니다." 배열을 수정하는 경우에는 배열이 이미 속성으로 존재하고 this.state그 값을 참조하여 새 값을 설정해야 setState()하므로 이전 상태의 함수를 인수로 받아들이는 형식을 사용해야합니다 . 예 : this.setState(prevState => ({ myArray: [...this.state.myArray, 'new value'] }));참조 : reactjs.org/docs/…
Bungle

103

상태를 직접 변경하지 않는 것이 좋습니다.

이후 React 버전에서 권장되는 접근 방식은 경합 상태를 방지하기 위해 상태를 수정할 때 업데이트 기능을 사용하는 것입니다.

배열 끝에 문자열 푸시

this.setState(prevState => ({
  myArray: [...prevState.myArray, "new value"]
}))

배열의 시작 부분으로 문자열 푸시

this.setState(prevState => ({
  myArray: ["new value", ...prevState.myArray]
}))

배열 끝으로 개체 푸시

this.setState(prevState => ({
  myArray: [...prevState.myArray, {"name": "object"}]
}))

객체를 배열의 시작 부분으로 푸시

this.setState(prevState => ({
  myArray: [ {"name": "object"}, ...prevState.myArray]
}))

1
이 대답을 사용했습니다. 또한 배열에 추가 할 때도 작동합니다.this.setState((prevState) => ({ myArray: [values, ...prevState.myArray], }));
Gus

1
이것은 허용되는 답변보다 훨씬 더 나은 접근 방식이며 React 문서에서 권장하는 방식으로 수행됩니다.
Ian J Miller

2
다른 답변은 자체 상태를 변경하는 경우 콜백 사용에 대한 최신 지침을 따르지 않기 때문에 이것을 +1합니다.
Matt Fletcher

상태 배열에 다른 배열 객체를 추가하는 방법은 무엇입니까?
Chandni

14

상태를 전혀 운영해서는 안됩니다. 적어도 직접적으로는 아닙니다. 어레이를 업데이트하려면 이와 같은 작업을 수행해야합니다.

var newStateArray = this.state.myArray.slice();
newStateArray.push('new value');
this.setState(myArray: newStateArray);

상태 개체에서 직접 작업하는 것은 바람직하지 않습니다. React의 불변성 도우미를 살펴볼 수도 있습니다.

https://facebook.github.io/react/docs/update.html


5
나는 우리가 왜 상태에서 작동 할 수 없는지, 즉 바람직하지 않은 이유를 알고 싶었지만이 대답이 올바른 대답이라고 믿습니다. 약간의 파고를 한 후에 다음 React 튜토리얼-Why Immutability is Important를 발견했습니다.이 튜토리얼 은 누락 된 정보를 채우는 데 도움이되었으며 튜토리얼 .slice()은 새 배열을 만들고 불변성을 유지 하는데도 사용 합니다. 도와 주셔서 감사합니다.
BebopSong 2018

11

.concat메서드를 사용하여 새 데이터로 배열 복사본을 만들 수 있습니다 .

this.setState({ myArray: this.state.myArray.concat('new value') })

그러나 특별한 행동을 조심 .concat- 배열을 전달할 때 방법 [1, 2].concat(['foo', 3], 'bar')에서 발생합니다 [1, 2, 'foo', 3, 'bar'].


1

이 코드는 저에게 효과적입니다.

fetch('http://localhost:8080')
  .then(response => response.json())
  .then(json => {
  this.setState({mystate: this.state.mystate.push.apply(this.state.mystate, json)})
})

3
Stack Overflow에 오신 것을 환영합니다! 소스 코드만으로 대답하지 마십시오. 솔루션 작동 방식에 대한 멋진 설명을 제공하십시오. 참조 : 좋은 답변을 어떻게 작성합니까? . 감사합니다
sɐunıɔ ןɐ qɐp

나는 이것을 시도했지만 소용이 없었다. 여기에 내 코드입니다fetch(`api.openweathermap.org/data/2.5/forecast?q=${this.searchBox.value + KEY} `) .then( response => response.json() ) .then( data => { this.setState({ reports: this.state.reports.push.apply(this.state.reports, data.list)}); });
henrie

그리고 나는 먼저 상태를 빈 배열로 초기화했습니다. 즉 this.state = { reports=[] }... pls 내가 뭘 잘못하고 있는지 알고 싶습니다
henrie

@Hamid Hosseinpour
henrie

1

반응 네이티브

u UI (예 : ur flatList)도 최신 상태로 유지하려면 PrevState를 사용합니다. 아래 예제에서 사용자가 버튼을 클릭하면 목록에 새 개체를 추가합니다 (모델과 UI 모두 )

data: ['shopping','reading'] // declared in constructor
onPress={() => {this.setState((prevState, props) => {
return {data: [new obj].concat(prevState.data) };
})}}. 

0

다음과 같은 방법으로 객체를 확인하고 업데이트 할 수 있습니다.

this.setState(prevState => ({
    Chart: this.state.Chart.length !== 0 ? [...prevState.Chart,data[data.length - 1]] : data
}));

0

여기에서는 객체를 이와 같은 상태 배열로 푸시 할 수 없습니다. 일반 배열에서 당신의 방식대로 밀 수 있습니다. 여기서 상태를 설정해야합니다.

this.setState({ 
     myArray: [...this.state.myArray, 'new value'] 
})

-1

이렇게 상태를 업데이트하려는 경우

   handleClick() {
        this.setState(
{myprop: this.state.myprop +1}
        })
    }

이 접근 방식을 고려하십시오

   handleClick() {
        this.setState(prevState => {
            return {
                count: prevState.count + 1
            }
        })
    }

기본적으로 prevState는 this.state를 작성합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.