この警告メッセージに直面するのは初めてです。
まだマウントされていないコンポーネントでsetStateを呼び出すことはできません。
フォロー:
これは何もしませんが、アプリケーションのバグを示している可能性があります。代わりに、
this.state
に直接割り当てるか、MyComponentコンポーネントで目的の状態を持つstate = {};
クラスプロパティを定義します。
「まだマウントされていない」の部分は、問題を引き起こす唯一の方法は、ボタンを表示するためにマウントする必要があるコンポーネントからボタンをクリックすることによって機能します。コンポーネントは、いつでもアンマウントされません。
このダミーコンポーネントは、アプリでエラーを再現します。
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-reactオブザーバーです)
編集:
コンポーネントインスタンスに関連するものが存在する必要があります。詳細な調査により、場合によっては、render関数内にハンドラーを作成するとこの警告が消えることが示されていますが、すべての場合ではありません。
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:
Webpack configのエントリから「react-hot-loader/patch」を削除しましたが、このような奇妙な問題はなくなりました。エラーメッセージ自体はまだ奇妙であり、これがコンソールに警告を引き起こすので、私はこれを答えとしていません。すべてがうまく動作します。
@ Amida のように、ホットローダーが問題のようです。使用している人
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true,
ReactHotModuleReplacement = true
});
startup.csでそれを削除すると、問題は消えます。理由はわかりませんが、これが現在の回避策です。
編集:
「react-hot-loader」および「webpack-hot-middleware」を最新バージョンに更新すると、問題が修正されました
このコード行をコードに追加するだけです
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>
);
}
}
テストの1つでこのエラーが発生している場合、コンポーネントにアクセスする前に、コンポーネントをrender
する必要があるかもしれません(つまり、単にlet app = new App;
を行うだけでは不十分です)。レンダリングは効果的に mountこの他の回答で説明されているように、コンポーネントとその子 を使用すると、 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 ( ... ) }
}