[解決済み] React useEffectが発生する。マウントされていないコンポーネントに対してReactの状態更新を実行できない
質問
データを取得するときに、次のようなメッセージが表示されます。アンマウントされたコンポーネントに対して React の状態更新を実行できません。アプリはまだ動作しますが、reactは私がメモリリークを引き起こしている可能性があることを示唆しています。
これはダメ押しですが、アプリケーションにメモリリークがあることを示しています。修正するには、useEffectクリーンアップ関数ですべてのサブスクリプションと非同期タスクをキャンセルします."。
なぜこの警告が出続けるのですか?
これらの解決策を調べてみました。
https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
https://developer.mozilla.org/en-US/docs/Web/API/AbortController
と表示されますが、これでも警告が表示されました。
const ArtistProfile = props => {
const [artistData, setArtistData] = useState(null)
const token = props.spotifyAPI.user_token
const fetchData = () => {
const id = window.location.pathname.split("/").pop()
console.log(id)
props.spotifyAPI.getArtistProfile(id, ["album"], "US", 10)
.then(data => {setArtistData(data)})
}
useEffect(() => {
fetchData()
return () => { props.spotifyAPI.cancelRequest() }
}, [])
return (
<ArtistProfileContainer>
<AlbumContainer>
{artistData ? artistData.artistAlbums.items.map(album => {
return (
<AlbumTag
image={album.images[0].url}
name={album.name}
artists={album.artists}
key={album.id}
/>
)
})
: null}
</AlbumContainer>
</ArtistProfileContainer>
)
}
編集します。
私のapiファイルでは
AbortController()
を追加し
signal
を使用しているので、リクエストをキャンセルすることができます。
export function spotifyAPI() {
const controller = new AbortController()
const signal = controller.signal
// code ...
this.getArtist = (id) => {
return (
fetch(
`https://api.spotify.com/v1/artists/${id}`, {
headers: {"Authorization": "Bearer " + this.user_token}
}, {signal})
.then(response => {
return checkServerStat(response.status, response.json())
})
)
}
// code ...
// this is my cancel method
this.cancelRequest = () => controller.abort()
}
私の
spotify.getArtistProfile()
は次のようになります。
this.getArtistProfile = (id,includeGroups,market,limit,offset) => {
return Promise.all([
this.getArtist(id),
this.getArtistAlbums(id,includeGroups,market,limit,offset),
this.getArtistTopTracks(id,market)
])
.then(response => {
return ({
artist: response[0],
artistAlbums: response[1],
artistTopTracks: response[2]
})
})
}
で解決されますが、私のシグナルは個々のapi呼び出しに使用されるので
Promise.all
で解決されます。
abort()
という約束ができないので、常に状態を設定することになります。
どのように解決するのか?
共有する
AbortController
の間に
fetch()
のリクエストは正しいアプローチです。
いつ
どんな
の
Promise
は中止されます。
Promise.all()
で拒否されます。
AbortError
:
function Component(props) {
const [fetched, setFetched] = React.useState(false);
React.useEffect(() => {
const ac = new AbortController();
Promise.all([
fetch('http://placekitten.com/1000/1000', {signal: ac.signal}),
fetch('http://placekitten.com/2000/2000', {signal: ac.signal})
]).then(() => setFetched(true))
.catch(ex => console.error(ex));
return () => ac.abort(); // Abort both fetches on unmount
}, []);
return fetched;
}
const main = document.querySelector('main');
ReactDOM.render(React.createElement(Component), main);
setTimeout(() => ReactDOM.unmountComponentAtNode(main), 1); // Unmount after 1ms
<script src="//cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.development.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.development.js"></script>
<main></main>
関連
-
[解決済み] React jsのonClickはメソッドに値を渡すことができない
-
[解決済み] Reactコンポーネント外でのクリックを検出する
-
[解決済み] Reactでネストした状態のプロパティを更新する方法
-
[解決済み】マウントされていないコンポーネントに対してReactの状態更新を行うことができない
-
[解決済み] JavaScriptでの大文字小文字を区別しない正規表現
-
[解決済み] jqueryはjavascriptのライブラリなのかフレームワークなのか?[クローズド]
-
[解決済み] ECMAScriptとは?
-
[解決済み] javascriptでオプションのパラメータを扱う
-
[解決済み] JavaScript で css プロパティを使用して HTML 要素の背景色を設定する方法
-
[解決済み] JavaScriptの文字列プリミティブとStringオブジェクトの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] jqueryでdivの要素がオーバーフローしていないかチェックする
-
[解決済み] チェックボックスが選択されているかどうかを確認するjQuery
-
[解決済み] 文字列が空白であるかどうかをチェックする
-
[解決済み] Javascript / jQueryでAndroid端末を検出する。
-
[解決済み] JavaScriptでの大文字小文字を区別しない正規表現
-
[解決済み] TypeScriptプロジェクトで既存のC#クラス定義を再利用する方法
-
[解決済み] Reactメモを使うべきではない場合とは?
-
[解決済み] Chromeのwebkitインスペクタで「Unsafe JavaScript attempt to access frame with URL...」というエラーが継続的に発生する。
-
[解決済み] javascriptでオプションのパラメータを扱う
-
[解決済み] JavaScript で css プロパティを使用して HTML 要素の背景色を設定する方法