はじめに
こんにちは。今週も開発のノーハウについて投稿させていただきます。
最近はReact Nativeを用いてweb開発をやっています。React Nativeはとても使いやすいフレームワークですが、たまたま変な問題が出ます。今回私はwebをテストしているときに、コンソールから下記の警告情報が出てきました:
Warning: Can't perform a React state update 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 a useEffect cleanup function.
この警告はよく見れるものであって、ググったら対策もいっぱいあるけれど、私の場合は若干違う気がします。
結論は最初に出す
とにかく、コンポーネント関数はデフォルト(メイン)コンポーネントの中に入れないほうが良いかも。
問題の再現
まずはソースコードを見てみましょう。
function Main() {
const [text, setText] = useState<string>("");
const TestComp = () => {
return(
<View>
<Image
style={{width:150,height:150}}
source={{uri: 'https://i.imgur.com/QHZtKLh.png'}}
{/* 画像はimgurから適当にとったもの */}
/>
</View>
)
}
return(
<View style={styles.container}>
<TextInput
style={styles.textInput}
onChangeText={text => setText(text)}
value={text}
/>
<TestComp />
</View>
);
}
const styles = StyleSheet.create({
// スタイルは適当に
});
export default Main;
ご覧の通り、ごく簡単のコードですが、TextInput
に早い速度で入力したら、上記のような警告情報が出てくるのです。
Warning: Can't perform a React state update 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 a useEffect cleanup function.
バージョン情報は以下です:
"dependencies": {
"expo": "~43.0.2",
"expo-status-bar": "~1.1.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-paper": "^4.10.0",
"react-native-responsive-screen": "^1.4.2",
"react-native-vector-icons": "^9.0.0",
"react-native-web": "0.17.1"
}
問題の分析と改善策
いろいろテストした結果、問題点はTestComp
が使っているpng画像です。
-
TestComp
の中に画像を使わないと、問題が発生しない - svg画像を使っているとき、問題が発生しない
-
TestComp
はMain
の外に入れるとき、問題が発生しない
ちなみに、Expo Snackにはこの警告が再現しません(Expoのバージョンは同じですが)。
さて、問題点を解明した以上、改善策も明らかに見られます。
TestComp
をMain
の外に入れれば、問題が回避できます。
ソースコードをこのようにしていきます。
function TestComp() {
//...
}
function Main() {
//...
}
const styles = StyleSheet.create({
//...
});
export default Main;
このようにコードを再アレンジしたら、警告も出なくなります。
果たして、回避策ができているけれど、なぜこのような警告情報が出てくるかわからないままです。
詳しい方が教えていただければ助かります。
最後に
この記事はあくまでも私個人(初心者として)の経験です。間違っているところ、もっと良い方法がございましたら、ぜひ教えてください。