IT Share you

실제로 구성 요소의 상태를 직접 수정할 수없는 이유는 무엇입니까?

shareyou 2021. 1. 8. 21:47
반응형

실제로 구성 요소의 상태를 직접 수정할 수없는 이유는 무엇입니까?


나는 React 튜토리얼과 문서 가 상태가 직접적으로 변경되어서는 안되며 모든 것이 진행되어야한다는 불확실한 용어로 경고한다는 것을 이해합니다 setState.

난 그냥 직접 전화 (동일한 기능에서) 다음 상태를 변경할 수 없으며, 정확히 이유를 이해하고자하는 this.setState({})을 트리거 단지 render.

예 : 아래 코드는 잘 작동하는 것 같습니다.

const React = require('react');

const App = React.createClass({
    getInitialState: function() {
        return {
            some: {
                rather: {
                    deeply: {
                        embedded: {
                            stuff: 1
                        }}}}};
    },
    updateCounter: function () {
        this.state.some.rather.deeply.embedded.stuff++;
        this.setState({}); // just to trigger the render ...
    },
    render: function() {
        return (
                <div>
                Counter value: {this.state.some.rather.deeply.embedded.stuff}
                <br></br>
                <button onClick={this.updateCounter}>inc</button>
                </div>
        );
    }
});

export default App;

나는 모두 다음 규칙을 따르지만 ReactJS가 실제로 어떻게 작동하는지, 무엇이 잘못 될 수 있는지 또는 위 코드에서 차선책인지에 대한 이해를 높이고 싶습니다.

this.setState문서 의 메모는 기본적으로 두 가지 문제점을 식별합니다.

  1. 상태를 직접 변경 한 다음 나중에 호출 this.setState하면 만든 변경을 대체 (덮어 쓰기?) 할 수 있습니다. 위의 코드에서 이것이 어떻게 일어날 수 있는지 모르겠습니다.
  2. 이는 비동기식 / 지연 방식으로 효과적으로 setState변경 될 수 this.state있으므로 this.state호출 직후 this.setState액세스 할 때 최종 변경된 상태에 액세스 할 수 있다고 보장 할 수 없습니다. this.setState업데이트 기능의 마지막 호출 인 경우 문제가되지 않습니다 .

에 대한 React 문서setState 는 다음과 같이 말합니다.

나중에 this.state호출 setState()하면 만든 돌연변이를 대체 할 수 있으므로 직접 돌연변이를 사용 하지 마십시오 . this.state불변 인 것처럼 취급하십시오 .

setState()즉시 변경되지는 않지만 this.state보류 상태 전환을 만듭니다. this.state이 메서드를 호출 한 후 액세스 하면 잠재적으로 기존 값을 반환 할 수 있습니다.

호출의 동기 작업이 보장되지 않으며 setState성능 향상을 위해 호출이 일괄 처리 될 수 있습니다.

setState()조건부 렌더링 논리가에서 구현되지 않는 한 항상 다시 렌더링을 트리거합니다 shouldComponentUpdate(). 변경 가능한 객체를 사용하고에서 로직을 구현할 수없는 경우 새 상태가 이전 상태와 다를 때만 shouldComponentUpdate()호출 setState()하면 불필요한 다시 렌더링을 방지 할 수 있습니다.

기본적으로 this.state직접 수정 하면 해당 수정 사항을 덮어 쓸 수있는 상황이 발생합니다.

귀하의 확장 질문 1) 및 2)와 관련하여 setState()즉각적이지 않습니다. 에 대한 직접적인 변경 사항을 포함하지 않을 수있는 진행 상황에 따라 상태 전환을 대기열에 넣습니다this.state . 즉시 적용되지 않고 대기열에 있기 때문에 직접 변경 사항을 덮어 쓰도록 중간에 무언가가 수정 될 수 있습니다.

다른 것이 없다면 직접 수정하지 않는 this.state것이 좋은 방법 이라고 생각하는 것이 더 나을 수 있습니다. 코드가 이러한 덮어 쓰기 또는 기타 문제가 발생할 수없는 방식으로 React와 상호 작용한다는 것을 개인적으로 알고 있을지 모르지만 다른 개발자 또는 향후 업데이트가 갑자기 이상하거나 미묘한 문제를 발견 할 수있는 상황을 만들고 있습니다.


이 답변은 React에서 직접 상태를 변경 / 변형하지 않도록 충분한 정보를 제공하는 것입니다.

React는 단방향 데이터 흐름을 따릅니다 . 의미, 반응 내부의 데이터 흐름은 순환 경로에 있어야하며 예상 될 것입니다.

유동이없는 React의 데이터 흐름

여기에 이미지 설명 입력

React가 이와 같이 작동하도록 개발자는 React를 함수형 프로그래밍 과 유사하게 만들었습니다 . 함수형 프로그래밍의 일반적인 규칙은 불변성 입니다. 크고 명확하게 설명하겠습니다.

단방향 흐름은 어떻게 작동합니까?

  • states 구성 요소의 데이터를 포함하는 데이터 저장소입니다.
  • view컴포넌트의이 상태에 기초하여 렌더링한다.
  • view화면에서 무언가를 변경해야 할 때 해당 값은 store.
  • To make this happen, React provides setState() function which takes in an object of new states and does an compare and merge(similar to object.assign()) over the previous state and adds the new state to the state data store.
  • Whenever the data in the state store changes, react will trigger an re-render with the new state which the view consumes and show it on the scree.

This cycle will continue throughout the component's lifetime.

If you see the above steps, it clearly shows a lot of things are happening behind when you change the state. So, when you mutate the state directly and call setState() with an empty object. The previous state will be polluted with your mutation. Due to which, the shallow compare and merge of two states will be disturbed or won't happen, because you'll have only one state now. This will disrupt all the React's Lifecycle Methods.

As a result, your app will behave abnormal or even crash. Most of the times, it won't affect your app because all the apps which we use for testing this are pretty small.

And another downside of mutation of Objects and Arrays in JavaScript is, when you assign an object or an array, you're just making a reference of that object or that array. When you mutate them, all the reference to that object or that array will be affected. React handles this in a intelligent way in the background and simply give us an API to make it work.

Most common errors done when handling states in react

//original state
this.state = {
   a: [1,2,3,4,5]
}

//changing the state in react
//need to add '6' in the array

//bad approach
const b = this.state.a.push(6)
this.setState({
  a: b
}) 

In the above example, this.state.a.push(6) will mutate the state directly. Assigning it to another variable and calling setState is same as what's shown below. As we mutated the state anyway, there's no point assigning it to another variable and calling setState with that variable.

 //same as 
 this.state.a.push(6)
 this.setState({})

Most of the people does this. This is so wrong. This breaks the beauty of React and it'll make you a bad programmer.

So, What's the best way to handle states in react? Let me explain.

When you need to change 'something' in the existing state, first get a copy of that 'something' from the current state.

//original state
    this.state = {
       a: [1,2,3,4,5]
    }

 //changing the state in react
 //need to add '6' in the array

 //create a copy of this.state.a
 //you can use ES6's destructuring or loadash's _.clone()
 const currentStateCopy = [...this.state.a]

Now, mutating currentStateCopy won't mutate the original state. Do operations over currentStateCopy and set it as the new state using setState()

currentStateCopy.push(6)
this.state({
 a: currentStateCopy
})

This is beautify right?

By doing this, all the references of this.state.a won't get affected until we use setState. This gives you control over your code and this'll help you write elegant test and make you confident about the performance of the code in production.

To answer your question,

Why can't I directly modify a component's state?


Yes, you can. But, you need to face the following consequences.

  1. When you scale, your'll be writting unmanageable code.
  2. You'll lose control of state across components.
  3. Instead of using React, you'll be writing custom codes over React.

Immutability is not necessary thing because Javascript is single threaded. But, It's a good to follow practice which will help you in the long run.

PS. I've written about 10000 lines of mutable React js code. If it breaks now, I don't know where to look into because all the values are mutated somewhere. When I realized this, I started writting immutable code. Trust me! That's the best thing you can do it to a product or an app.

Hope this helps!


the simplest answer to "

Why can't I directly modify a component's state:

is all about Updating phase.

when we update the state of a component all it's children are going to be rendered as well. or our entire component tree rendered.

but when i say our entire component tree is rendered that doesn’t mean that the entire DOM is updated. when a component is rendered we basically get a react element, so that is updating our virtual dom.

React will then look at the virtual DOM, it also has a copy of the old virtual DOM, that is why we shouldn’t update the state directly, so we can have two different object references in memory, we have the old virtual DOM as well as the new virtual DOM.

then react will figure out what is changed and based on that it will update the real DOM accordingly .

hope it helps.


나의 현재 이해에 기반 대답 :

경우 당신이 사용하지 않는 shouldComponentUpdate 또는 다른 라이프 사이클 방법 (같은 componentWillReceiveProps, componentWillUpdate그리고 componentDidUpdate) 당신이 과거와 소품을 비교 / 주

그때

mutate state다음를 호출 setState()하는 것은 괜찮습니다. 그렇지 않으면 괜찮지 않습니다.

참조 URL : https://stackoverflow.com/questions/37755997/why-cant-i-directly-modify-a-components-state-really

반응형