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


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.props와 this.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.