programing

아직 마운트되지 않은 구성 요소에서 setState를 호출할 수 없습니다.

javajsp 2023. 3. 15. 19:19

아직 마운트되지 않은 구성 요소에서 setState를 호출할 수 없습니다.

이런 경고 메시지는 처음입니다.

아직 마운트되지 않은 구성 요소에서 setState를 호출할 수 없습니다.

이하에 나타냅니다.

이것은 no-op이지만, 애플리케이션의 버그를 나타내고 있는 경우가 있습니다.대신, 에 할당합니다.this.state직접 또는 정의하다state = {};원하는 상태의 클래스 속성을 MyComponent 컴포넌트에서 지정합니다.

"아직 마운트되지 않은" 부분은 이 문제를 일으키는 유일한 방법은 버튼을 표시하기 위해 마운트해야 하는 컴포넌트에서 버튼을 클릭하여 함수를 호출하는 것이기 때문에 실제로는 의미가 거의 없습니다.컴포넌트는 지정된 시간에 마운트 해제되지 않습니다.

이 더미 컴포넌트는 내 앱에서 오류를 재현합니다.

import PropTypes from 'prop-types'
import React from 'react'

export default class MyComponent extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      initial: 'state'
    }
    this.clickMe = this.clickMe.bind(this)
  }

  clickMe () {
    this.setState({
      some: 'new state'
    })
  }

  render () {
    return (
      <div>
        <button onClick={this.clickMe}>click</button>
      </div>
    )
  }
}

사용하고 있는 것:

"react": "16.3.2",
"react-dom": "16.3.2",
"mobx": "4.2.0",
"mobx-react": "5.1.2",

최신 React/mobx 버전에서 누락된 것이 있습니까?(컴포넌트는 mobx 관련 정보를 사용하지 않지만, 그 부모는 mobx를 사용하는 옵서버입니다.)

편집:

컴포넌트 인스턴스와 관련된 것이 있을 것입니다.더 자세한 조사 결과 렌더 함수 내에 핸들러를 작성하면 이 경고가 사라지지만 모든 경우에 이 경고는 사라지지 않는 것으로 나타났습니다.

class MyComponent extends React.component {
  constructor (props) {
    // ...
    this.clickMeBound = this.clickMe.bind(this)
  }

  clickMe () {
    ...
  }

  render () {
    // works
    <button onClick={() => {this.clickMe()}}>click arrow in render</button>

    // warning: Can't call setState on a component that is not yet mounted.
    <button onClick={this.clickMeBound}>click bound</button>
  }
}

편집 2:

Web pack 설정의 엔트리에서 「react-hot-loader/patch」를 삭제해, 이와 같은 이상한 문제가 없어졌습니다.오류 메시지 자체가 여전히 이상하고 콘솔에 경고가 표시되므로 답변으로 표시하지 않습니다.그래도 다 잘 되고 있어요.

이 경고는 컨스트럭터에서 clickMe 메서드에 대한 참조를 설정하고 그 후에 setState()를 사용하기 때문입니다.

constructor (props) {
    super(props)
    this.state = {
       initial: 'state',
       some: ''          
    }
   this.clickMe = this.clickMe.bind(this);   <--- This method
  }

 clickMe () {
   this.setState({
     some: 'new state'    <-- the setState reference that is causing the issue
   })
  }

componentWillMount() 또는 ComponentDidMount()와 같은 라이프사이클 메서드에서 이 . clickMe = this . clickMe . bind ( this )를 제거해 보십시오.react 16 이상의 경우 componentWillMount 메서드 "SAFE_" 접두사를 사용할 수 있습니다.[SAFE_componentWillMount]

 componentWillMount() {
      this.clickMe = this.clickMe.bind(this);
 }

clickMe () {
   this.setState({
     some: 'new state'    
   })
  }

이 기능을 사용하면,componentDidMount()방법.컴포넌트의 라이프 사이클에서 React 매뉴얼에 나타나 있듯이 리모트엔드포인트에서 데이터를 로드해야 할 경우 네트워크 요구를 인스턴스화하기 위해 이 장소가 적합합니다.또, 콜을 실시할 수도 있습니다.setState()에 바로componentDidMount().

다음과 같이 합니다.

componentDidMount(){
  this.clickMe = this.clickMe.bind(this);
}
clickMe () {
  this.setState({
    some: 'new state'
  })
}

코드에 다음 행을 추가합니다.

export default class MyComponent extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
       initial: 'state',
       some: ''          // <-------  THIS LINE
    }
   this.clickMe = this.clickMe.bind(this)
  }

 clickMe () {
   this.setState({
     some: 'new state'
   })
  }

 render () {
   return (
     <div>
       <button onClick={this.clickMe}>click</button>
     </div>
   );
  }
}

구성 요소가 아직 마운트되지 않았으므로 생성자에서 setState를 사용하면 안 됩니다.이 경우 click Me() 메서드는 setState()를 호출합니다.
대신 직접 상태를 초기화하십시오.를 들면 ㅇㅇㅇㄹㄹㄹㄹ.

constructor(props) {
    super(props);
    // Don't call this.setState() here!
    this.state = { counter: 0 };
    this.handleClick = this.handleClick.bind(this);
}

예: https://reactjs.org/docs/react-component.html#constructor 에서

setState()는 재렌더링으로 상태변경을 반영하기 위해 사용됩니다.컴포넌트는 아직 렌더링되지 않았기 때문에 직접 상태를 변경할 수 있으며 변경은 render() 메서드의 호출에 반영됩니다.

@Amida가 말했듯이 핫로더가 문제인 것 같습니다.사용하고 있는 사람

app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
    HotModuleReplacement = true,
    ReactHotModuleReplacement = true
});

Startup.cs 에서 삭제하면, 문제가 해소됩니다.이유는 모르겠지만, 이것이 현재 저의 해결 방법입니다.

편집:

"react-hot-loader" 및 "webpack-hot-middleware"를 최신 버전으로 업데이트하면 문제가 해결되었습니다.

중 이 " " "가 필요할 수 .render 전 에 대한 컴포넌트( '컴포넌트'를 실행하는 것)let app = new App;충분하지 않습니다.)렌더링에 의해 컴포넌트와 그 하위 컴포넌트가 효과적으로 마운트됩니다(다른 답변에서 설명한 바와 같이).그러면 결과 오브젝트를 사용하여 작업을 트리거하지 않고 실행할 수 있습니다.setState한 러러. 단순한App.test.js§:

import App from './App';

it('renders without crashing', () => {
  const div = document.createElement('div');
  ReactDOM.render(<App />, div); // <-- App component mounted here
  // without JSX: ReactDOM.render(React.createElement(App), div)
  ReactDOM.unmountComponentAtNode(div);
});

test('array length decreased after removal', () => {
  const div = document.createElement('div');
  let app = ReactDOM.render(<App />, div); // <-- App component mounted here
  const origArrLen = app.state.arr.length;

  app.removeAtIndex(0);
  expect(app.state.arr.length).toEqual(origArrLen - 1);
  ReactDOM.unmountComponentAtNode(div);
});

갔지?App츠키다

class App extends Component {
  state = {
    arr: [1,2,3]
  };

  removeAtIndex = index => {
    const { arr } = this.state;
    this.setState({ arr: arr.filter((el, i) => i !== index) });
  };
  // render() { return ( ... ) }
}

브라우저가 화면을 업데이트하기 전에 componentDidMount()에서 초기 상태를 할당하고 즉시 setState()를 호출하여 추가 렌더링을 트리거해야 합니다.경우 render() 메서드는 두 번 호출되며 사용자는 중간 상태를 볼 수 없습니다.

코드는 다음과 같습니다.

 import PropTypes from 'prop-types'
import React from 'react'

export default class MyComponent extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      initial: 'state'  // initialize your state in the constructor()
    }    
  }
  componentDidMount(){
  this.clickMe = this.clickMe.bind(this)
  clickMe () {   // call setState() in componentDidMount()
    this.setState({
      some: 'new state'
    })
  }
}

  render () {
    return (
      <div>
        <button onClick={this.clickMe}>click</button>
      </div>
    )
  }
}

 

언급URL : https://stackoverflow.com/questions/50162522/cant-call-setstate-on-a-component-that-is-not-yet-mounted