如何理解 React Native 中的 useEffect

1. 你可以把它想象成你手机的 "智能助理"。

  • 核心比喻:你的私人智能助理
  • 想象一下,你请了一个智能助理来帮你处理各种事情。useEffect 就是这个助理,它的工作模式是:
    "当 [某些事情] 发生时,请帮我执行 [某个任务]。"

2. 基础语法:给助理下达指令

javascript 复制代码
useEffect(() => {
  // 这是你要助理执行的任务(比如:打电话、发短信)
  console.log('助理正在工作...');
  
  return () => {
    // 这是清理工作(比如:挂断电话、取消任务)
    console.log('助理在清理现场...');
  };
}, [/* 监听列表:当这些东西变化时,助理才工作 */]);

3. 三种工作模式(重要!)

模式一:随叫随到的助理(无依赖数组)

javascript 复制代码
useEffect(() => {
  console.log('老板,我随时待命!每次组件更新我都会工作!');
});

比喻 :助理紧盯着你的一举一动,你每次呼吸他都会问"需要帮忙吗?"
使用场景:很少用,因为太烦人了!

模式二:专注特定任务的助理(有依赖数组)

javascript 复制代码
const [count, setCount] = useState(0);
const [name, setName] = useState('小明');

useEffect(() => {
  console.log(`计数变成了: ${count}, 我正在处理相关任务!`);
}, [count]); // ← 只监听 count 的变化

比喻 :助理只关心你的银行余额变化,其他事情不打扰你。
实际例子:

javascript 复制代码
// 当用户ID变化时,重新获取用户数据
useEffect(() => {
  fetchUserData(userId);
}, [userId]); // 只有userId变化时才执行

模式三:一次性的助理(空依赖数组)

javascript 复制代码
useEffect(() => {
  console.log('老板,我只在组件第一次出现时工作一次,以后就不打扰你了!');
}, []); // ← 空数组,表示不监听任何变化

比喻 :助理在你入职第一天帮你设置好办公桌,然后就不再管了。
实际例子

javascript 复制代码
// 组件首次加载时获取数据
useEffect(() => {
  loadInitialData();
}, []); // 只在组件挂载时执行一次

4. 清理工作:助理的善后职责

javascript 复制代码
useEffect(() => {
  // 任务:开始监听服务器消息
  const subscription = listenToServerMessages();
  
  return () => {
    // 清理:取消监听(避免内存泄漏)
    subscription.unsubscribe();
    console.log('取消监听了,节省手机资源!');
  };
}, []);

比喻:助理帮你租了一间办公室,当你搬走时,他会帮你退租。

5. 实际 React Native 场景示例

场景一:监听网络状态变化

javascript 复制代码
import { useEffect, useState } from 'react';
import { NetInfo } from 'react-native';

const NetworkStatus = () => {
  const [isConnected, setIsConnected] = useState(true);
  
  useEffect(() => {
    // 任务:开始监听网络状态
    const unsubscribe = NetInfo.addEventListener(state => {
      setIsConnected(state.isConnected);
    });
    
    // 清理:组件卸载时取消监听
    return unsubscribe;
  }, []); // 空数组:只在组件创建时监听一次
  
  return <Text>网络状态: {isConnected ? '已连接' : '断开'}</Text>;
};

场景二:根据搜索关键词请求数据

javascript 复制代码
const SearchScreen = () => {
  const [searchText, setSearchText] = useState('');
  const [results, setResults] = useState([]);
  
  useEffect(() => {
    // 当搜索关键词变化时,发起搜索请求
    if (searchText.length > 2) { // 只有输入超过2个字符才搜索
      searchAPI(searchText).then(data => {
        setResults(data);
      });
    }
  }, [searchText]); // 监听 searchText 的变化
  
  return (
    <View>
      <TextInput 
        value={searchText}
        onChangeText={setSearchText}
        placeholder="输入搜索关键词"
      />
      <FlatList data={results} renderItem={/* ... */} />
    </View>
  );
};

场景三:定时器任务

javascript 复制代码
const TimerComponent = () => {
  const [seconds, setSeconds] = useState(0);
  
  useEffect(() => {
    // 任务:每秒更新一次时间
    const interval = setInterval(() => {
      setSeconds(prev => prev + 1);
    }, 1000);
    
    // 清理:清除定时器
    return () => clearInterval(interval);
  }, []); // 空数组:只需要设置一次定时器
  
  return <Text>已经运行了 {seconds} 秒</Text>;
};

6. 常见错误和正确做法

❌ 错误做法:忘记依赖

javascript 复制代码
const [count, setCount] = useState(0);
const [double, setDouble] = useState(0);

useEffect(() => {
  setDouble(count * 2); // 依赖了count,但没声明
}, []); // ❌ 应该写成 [count]

✅ 正确做法:声明所有依赖

javascript 复制代码
useEffect(() => {
  setDouble(count * 2);
}, [count]); // ✅ 明确声明依赖

快速记忆口诀

javascript 复制代码
useEffect 三兄弟,依赖数组定规矩:
[]      一次性的,创建之后不搭理;
[value] 专注型的,值变我才工作;
不写[]  烦人型的,天天盯着你变化;

记得return清理函数,内存泄漏远离咱!

7. 总结

useEffect 就是你的智能任务管家:

什么时候工作? → 看依赖数组 [] 里监听什么

做什么工作? → 写在函数体里 {}

结束后清理? → 写在返回函数里 return () => {}

相关推荐
helloyangkl37 分钟前
前端——不同环境下配置env
前端·javascript·react.js
竹秋…39 分钟前
webpack搭建react开发环境
前端·react.js·webpack
甜味弥漫1 小时前
JavaScript新手必看系列之预编译
前端·javascript
用户6600676685391 小时前
搞懂作用域链与闭包:JS底层逻辑变简单
前端·javascript
没落英雄2 小时前
简单了解 with
前端·javascript
小小弯_Shelby2 小时前
vue项目源码泄露漏洞修复
前端·javascript·vue.js
小皮虾2 小时前
拒绝卡顿!小程序图片本地“极速”旋转与格式转换,离屏 Canvas 性能调优实战
前端·javascript·微信小程序
soul968162 小时前
react-native-promise-portal:React Native 弹窗管理的新思路
react native
汤姆Tom2 小时前
前端转战后端:JavaScript 与 Java 对照学习指南 (第一篇 - 深度进阶版)
java·javascript
瓶子in2 小时前
JavaScript数组去重的多种实现方式
javascript