如何理解 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 () => {}

相关推荐
lyj1689972 小时前
CSS中 min() max() clamp()函数
前端·javascript·css
我的div丢了肿么办3 小时前
echarts4升级为echarts5的常见问题
前端·javascript·echarts
豆豆豆大王4 小时前
HTML 与 JavaScript 结合 “点击按钮弹出提示” 的交互功能
javascript·html·交互
乖女子@@@4 小时前
React-props的children属性
前端·javascript·react.js
八月十八4 小时前
React常用Hooks及使用示例大全
前端·javascript·react.js
长安——归故李5 小时前
【PLC程序学习】
java·c语言·javascript·c++·python·学习·php
WDyinh5 小时前
积分球领取补位动画实现
前端·javascript
前端开发爱好者5 小时前
v5.0 版本发布!Vue3 生态最强大的 3D 开发框架!
前端·javascript·vue.js
mumu1307梦6 小时前
html 占位符
前端·javascript·html