programing

React.js: setState 덮어쓰기, 병합 안 함

telecom 2023. 3. 21. 21:30
반응형

React.js: setState 덮어쓰기, 병합 안 함

리액트는 처음입니다.JS와 저는 석조 양식의 레이아웃을 만드는 실험을 하고 있습니다.

각 요소를 DOM에 렌더링한 후 각 항목을 루프하고 위의 요소를 기준으로 x 및 y 위치를 적용해야 합니다.

초기 모델은 다음과 같습니다.

[
  {
    "title": "The Forrest",
    "description": "some cool text",
    "imgSmallSrc": "/img/img4-small.jpg",
    "imgAlt": "Placeholder image",
    "tags": [
        "Design",
        "Mobile",
        "Responsive"
    ],
    "date": 1367154709885,
    "podStyle": {
      "width": 253
    }
  }
]

(짧게 하기 위해 보여드린 아이템은 1개뿐입니다).

루프가 완료되고 x 및 y 데이터가 확보되면 이 값을 에 적용합니다.podStyle물건.나는 전화한다setState()다음 데이터를 사용합니다.

[
  {
    "podStyle": {
      "x": 0,
      "y": 0,
      "height": 146,
      "width": 253
    }
  }
]

이렇게 하면 모델에서 현재 데이터가 모두 제거되고 데이터만 남게 됩니다.podStyle제가 이 합병이 어떻게 진행되는지 오해하고 있는 건가요?

상태가 오브젝트인 경우:

getInitialState: function() {
  return { x: 0, y: 0 };
}

사용할 수 있습니다.setState개체에서 개별 키를 설정하려면:

this.setState({ x: 1 }); // y still == 0

React는 상태를 지능적으로 병합하지 않습니다. 예를 들어 다음과 같이 작동하지 않습니다.

getInitialState: function() {
  return {
    point: { x: 0, y: 0 },
    radius: 10
  };
}

this.setState({point: {x: 1}});
// state is now == {point: {x: 1}, radius: 10} (point.y is gone)

[편집]

@ssorallen에서 설명한 것처럼 불변 도우미를 사용하여 원하는 효과를 얻을 수 있습니다.

var newState = React.addons.update(this.state, {
  point: { x: {$set: 10} }
});
this.setState(newState);

예에 대해서는, 다음의 JSFiddle참조해 주세요.http://jsfiddle.net/BinaryMuse/HW6w5/

합이 얕아서this.setState({point})(ed: this.state.time)는 그대로 유지되지만 (ed: this.state)는 완전히 대체됩니다.포인트)

https://facebook.github.io/react/docs/state-and-lifecycle.html#state-updates-are-merged

기존 답변에 대해 ES7+ 관점을 제공하려면 transform-object-rest-spread 대신Object.assign():

class MyComponent extends React.Component {
    state = {
        point: { 
            x: 0, 
            y: 0,
        },
        radius: 10,
    }

    handleChange = () => {
        this.setState((prevState, props) => ({
            point: {
                // rest operator (...) expands out to:
                ...prevState.point, // x:0, y:0,
                y: 1, // overwrites old y
            },
            // radius is not overwritten by setState
        }));
    }

    render() {
        // omitted
    }
}

.babelrc (또한 babel 프리셋스테이지2로부터의 트랜스폼클래스 속성 필요)

{
    "presets": ["es2015", "stage-2", "react"],
    "plugins": ["transform-object-rest-spread"],
}

2018-04-22 갱신

@sheljohn이 지적했듯이 (감사합니다!)를 언급하며this.state안에서.setState신뢰할 수 없습니다.

왜냐면this.props그리고.this.state는 비동기적으로 갱신될 수 있으므로 다음 상태를 계산할 때 해당 값에 의존하지 마십시오.

...

수정하려면 다음 형식을 사용합니다.setState()오브젝트가 아닌 기능을 받아들입니다.이 함수는 첫 번째 인수로 이전 상태를 수신하고 업데이트가 두 번째 인수로 적용될 때의 소품

https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

예를 들어 다음과 같습니다.

getInitialState: function() {
    return {
        something: { x: 0, y: 0 },
        blah: 10
    };
}

var state = Object.assign(this.state, {
    something: Object.assign(this.state.something, { y: 50 }),
});

this.setState(state);

트리를 하드 코딩하는 것보다 재귀적/심층적이었으면 좋겠지만, 그건 독자에게 맡기겠습니다.

언급URL : https://stackoverflow.com/questions/24898012/react-js-setstate-overwriting-not-merging

반응형