[javascript] ReactJS에서 상태 배열의 올바른 수정

state배열 끝에 요소를 추가하고 싶습니다 . 올바른 방법입니까?

this.state.arrayvar.push(newelement);
this.setState({arrayvar:this.state.arrayvar});

대신 배열을 수정 push하면 문제가 발생할 수 있다는 것이 우려됩니다. 안전합니까?

어레이의 사본을 만들고 setStateing을 낭비하는 대안 .



답변

문서 반응 말합니다 :

이 상태를 불변 인 것처럼 취급하십시오.

귀하는 push직접 상태를 돌연변이하고 다시 나중에 상태를 “재설정”경우에도 그 잠재적으로 발생하기 쉬운 코드를 에러가 발생할 수 있습니다. F.ex, 그것은 같은 수명주기 방법 componentDidUpdate이 트리거되지 않을 수 있습니다.

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

this.setState(prevState => ({
  arrayvar: [...prevState.arrayvar, newelement]
}))

메모리 “폐기물”은 비표준 상태 수정을 사용하여 발생할 수있는 오류와 비교할 때 문제가되지 않습니다.

이전 React 버전의 대체 구문

concat새 배열을 반환하므로 깨끗한 구문을 얻는 데 사용할 수 있습니다 .

this.setState({
  arrayvar: this.state.arrayvar.concat([newelement])
})

ES6에서는 Spread Operator를 사용할 수 있습니다 .

this.setState({
  arrayvar: [...this.state.arrayvar, newelement]
})


답변

를 사용하는 경우 가장 쉽습니다 ES6.

initialArray = [1, 2, 3];

newArray = [ ...initialArray, 4 ]; // --> [1,2,3,4]

새로운 배열은 [1,2,3,4]

React 에서 상태를 업데이트하려면

this.setState({
         arrayvar:[...this.state.arrayvar, newelement]
       });

배열 파괴에 대해 더 알아보기


답변

가장 간단한 방법 ES6:

this.setState(prevState => ({
    array: [...prevState.array, newElement]
}))


답변

React는 업데이트를 일괄 처리 할 수 ​​있으므로 올바른 접근 방식은 setState에 업데이트를 수행하는 기능을 제공하는 것입니다.

React 업데이트 애드온의 경우 다음이 안정적으로 작동합니다.

this.setState( state => update(state, {array: {$push: [4]}}) );

또는 concat ()의 경우 :

this.setState( state => ({
    array: state.array.concat([4])
}));

다음은 https://jsbin.com/mofekakuqi/7/edit?js , 출력이 잘못되었을 경우 발생하는 결과의 예입니다.

React가 setTimeout 콜백 내에서 업데이트를 일괄 처리하지 않기 때문에 setTimeout () 호출에 세 개의 항목이 올바르게 추가됩니다 ( https://groups.google.com/d/msg/reactjs/G6pljvpTGX0/0ihYw2zK9dEJ 참조 ).

버기 onClick은 “Third”만 추가하지만 고정 된 것에는 F, S 및 T가 예상대로 추가됩니다.

class List extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      array: []
    }

    setTimeout(this.addSome, 500);
  }

  addSome = () => {
      this.setState(
        update(this.state, {array: {$push: ["First"]}}));
      this.setState(
        update(this.state, {array: {$push: ["Second"]}}));
      this.setState(
        update(this.state, {array: {$push: ["Third"]}}));
    };

  addSomeFixed = () => {
      this.setState( state =>
        update(state, {array: {$push: ["F"]}}));
      this.setState( state =>
        update(state, {array: {$push: ["S"]}}));
      this.setState( state =>
        update(state, {array: {$push: ["T"]}}));
    };



  render() {

    const list = this.state.array.map((item, i) => {
      return <li key={i}>{item}</li>
    });
       console.log(this.state);

    return (
      <div className='list'>
        <button onClick={this.addSome}>add three</button>
        <button onClick={this.addSomeFixed}>add three (fixed)</button>
        <ul>
        {list}
        </ul>
      </div>
    );
  }
};


ReactDOM.render(<List />, document.getElementById('app'));


답변

주석에 언급 된 @ nilgun과 같이 반응 불변성 도우미를 사용할 수 있습니다 . 나는 이것이 매우 유용하다는 것을 알았다.

문서에서 :

간단한 푸시

var initialArray = [1, 2, 3];
var newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]

initialArray는 여전히 [1, 2, 3]입니다.


답변

기능 컴포넌트를 사용하는 경우 다음과 같이 사용하십시오.

const [chatHistory, setChatHistory] = useState([]); // define the state

const chatHistoryList = [...chatHistory, {'from':'me', 'message':e.target.value}]; // new array need to update
setChatHistory(chatHistoryList); // update the state


답변

배열에 새로운 요소를 추가 push()하려면 답이되어야합니다.

배열의 요소를 제거하고 상태를 업데이트하려면 아래 코드가 적합합니다. splice(index, 1)작동하지 않습니다.

const [arrayState, setArrayState] = React.useState<any[]>([]);
...

// index is the index for the element you want to remove
const newArrayState = arrayState.filter((value, theIndex) => {return index !== theIndex});
setArrayState(newArrayState);