非同期メソッドの問題が原因でエラーメッセージが表示されます。私の端末で私は見ています:
Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
- node_modules/fbjs/lib/warning.js:33:20 in printWarning
- node_modules/fbjs/lib/warning.js:57:25 in warning
- node_modules/react-native/Libraries/Renderer/ReactNativeRenderer-dev.js:12196:6 in warnAboutUpdateOnUnmounted
- node_modules/react-native/Libraries/Renderer/ReactNativeRenderer-dev.js:13273:41 in scheduleWorkImpl
- node_modules/react-native/Libraries/Renderer/ReactNativeRenderer-dev.js:6224:19 in enqueueSetState
- node_modules/react/cjs/react.development.js:242:31 in setState
* router/_components/item.js:51:16 in getImage$
- node_modules/regenerator-runtime/runtime.js:62:44 in tryCatch
- node_modules/regenerator-runtime/runtime.js:296:30 in invoke
- ... 13 more stack frames from framework internals
getImage$
を具体的に指摘していることに気付きました
そのセクションに使用しているコードは次のとおりです。
export default class extends Component {
constructor(props) {
super(props);
const { item } = props
const bindThese = { item }
this.boundActionCreators = bindActionCreators(bindThese)
this.state = {
image: require('../../static/logo.png'),
ready: false,
showOptions: this.props.showOptions
}
this.getImage = this.getImage.bind(this)
this.renderNotAdmin = this.renderNotAdmin.bind(this)
this.renderAdmin = this.renderAdmin.bind(this)
this.handleOutOfStock = this.handleOutOfStock.bind(this)
}
async getImage(img) {
let imgUri = await Amplify.Storage.get(img)
let uri = await CacheManager.get(imgUri).getPath()
this.setState({
image: { uri },
ready: true
})
}
componentDidMount() {
this.getImage(this.props.item.image)
}
この非同期メソッドでcomponentWillUnmount
を使用する方法を見つけようとしています。どうすればいいですか?
ありがとう!
isMounted
Reactパターンを使用して、ここでのメモリリークを回避できます。
コンストラクターで:
constructor(props) {
super(props);
this._isMounted = false;
// rest of your code
}
componentDidMount() {
this._isMounted = true;
this._isMounted && this.getImage(this.props.item.image);
}
あなたのcomponentWillUnmount
componentWillUnmount() {
this._isMounted = false;
}
あなたの中にいるときgetImage()
async getImage(img) {
let imgUri = await Amplify.Storage.get(img)
let uri = await CacheManager.get(imgUri).getPath()
this._isMounted && this.setState({
image: { uri },
ready: true
})
}
Axiosを使用する推奨アプローチは、キャンセル可能なプロミスパターンに基づいています。そのため、cancelToken subscription
を使用してコンポーネントをアンマウントしながら、ネットワーク呼び出しをキャンセルできます。以下が Axios Cancellation のリソースです
React blog から
ComponentDidMountで_isMountedプロパティをtrueに設定し、componentWillUnmountでfalseに設定し、この変数を使用してコンポーネントのステータスを確認するだけです。
理想的には、キャンセル可能なコールバックを使用してこれを修正するのが理想的ですが、ここでは最初の解決策が適しているようです。
絶対すべきではないのはisMounted()関数を使用することです。これは非推奨になる可能性があります。
ComponentWillUnmount()メソッドでthis.mounted = falseを設定し、componentDidMount()メソッドでthis.mounted = trueを設定する必要があります。
SetState更新は、componentDidMount()メソッドで宣言するための条件ベースの必要性です。
componentDidMount() {
this.mounted = true;
var myVar = setInterval(() => {
let nextPercent = this.state.percentage+10;
if (nextPercent >= 100) {
clearInterval(myVar);
}
if(this.mounted) {
this.setState({ percentage: nextPercent });
}
}, 100);
}
componentWillUnmount(){
this.mounted = false;
}