Skip to content
鼓励作者:欢迎打赏犒劳

react数据监听

监听普通字段

js
import {useEffect, useState} from 'react';


function App() {
    const [name, setName] = useState('Tom');
    const [age, setAge] = useState(18);
    const [summary, setSummary] = useState('');

    useEffect(() => {
        // 只要 name 或 age 任意一个变了,这里就会执行
        // 并且这里的 name 和 age 都是最新的值
        const newSummary = `姓名:${name},年龄:${age}`;
        setSummary(newSummary);

    }, [name, age]); // 👈 监听这两个字段

    return (
        <div>
            <p>{summary}</p>
            <button onClick={() => setAge(age + 1)}>年龄+1</button>
        </div>
    );
}

export default App;

监听对象-方法1

重新赋值一个新对象

js
import {useEffect, useState} from 'react';


function App() {
    const [config, setConfig] = useState({ mode: 'dark', version: 1 });
    const [summary, setSummary] = useState({});
    useEffect(() => {
        console.log('⚠️ 监听到了 config 变化!');
        // 注意:这里千万不要直接修改 config 对象,否则会导致死循环
        setSummary(config);
    }, [config]); // 👈 监听整个对象

    const updateConfig = () => {
        // ✅ 正确做法:创建一个新的对象(新内存地址)
        setConfig({ ...config, version: config.version + 1 });
    };

    return (
        <div>
            <p>{JSON.stringify(summary)}</p>
            <button onClick={updateConfig}>年龄+1</button>
        </div>
    );
}

export default App;

监听对象-方法2

简单粗暴,适合对象属性很多且都需要监听的情况

js
import { useEffect, useRef, useState } from 'react';

function App() {
    const [form, setForm] = useState({ a: 1, b: 2 });
    const [lastChangedField, setLastChangedField] = useState(null);
    // 记住上一次的值,必须用useRef
    const prevFormRef = useRef(form);

    useEffect(() => {
        // 找出哪个字段发生了变化
        const prevForm = prevFormRef.current;
        const changedFields = [];

        if (prevForm.a !== form.a) {
            changedFields.push(`a: ${prevForm.a} → ${form.a}`);
        }
        if (prevForm.b !== form.b) {
            changedFields.push(`b: ${prevForm.b} → ${form.b}`);
        }

        if (changedFields.length > 0) {
            setLastChangedField(changedFields.join(', '));
            console.log('表单的任意字段变了!', changedFields);
        }

        // 更新 ref
        prevFormRef.current = form;
    }, [JSON.stringify(form)]);

    const updateA = () => {
        setForm(prev => ({ ...prev, a: prev.a + 1 }));
    };

    const updateB = () => {
        setForm(prev => ({ ...prev, b: prev.b + 1 }));
    };

    const resetForm = () => {
        setForm({ a: 1, b: 2 });
        setLastChangedField(null);
    };

    return (
        <div style={{ padding: '20px', fontFamily: 'Arial' }}>
            <h2>表单监控</h2>

            <div style={{ marginBottom: '20px' }}>
                <p>当前表单值:</p>
                <p>a = <strong>{form.a}</strong></p>
                <p>b = <strong>{form.b}</strong></p>
            </div>

            <div style={{ marginBottom: '20px' }}>
                <button onClick={updateA} style={{ marginRight: '10px' }}>
                    增加 a
                </button>
                <button onClick={updateB} style={{ marginRight: '10px' }}>
                    增加 b
                </button>
                <button onClick={resetForm}>
                    重置
                </button>
            </div>

            {lastChangedField && (
                <div style={{
                    padding: '10px',
                    backgroundColor: '#e3f2fd',
                    borderRadius: '5px',
                    borderLeft: '4px solid #2196f3'
                }}>
                    🔔 发生变化:{lastChangedField}
                </div>
            )}

            <div style={{
                marginTop: '20px',
                padding: '10px',
                backgroundColor: '#f5f5f5',
                borderRadius: '5px',
                fontSize: '12px',
                color: '#666'
            }}>
                💡 提示:使用 JSON.stringify 监听整个对象的变化
            </div>
        </div>
    );
}

export default App;

监听对象字段

js
import {useEffect, useRef, useState} from 'react';


function App() {
    const [userInfo, setUserInfo] = useState({ name: 'Jack', age: 20, token: 'abc' });
    const isFirstRender = useRef(true);

    // ✅ 场景:我只关心 age 变了没,name 变了我不 care
    useEffect(() => {
        // 如果你希望只在 age 真正变化时执行(而排除初始挂载),可以加一个 useRef 跳过第一次:
        if (isFirstRender.current) {
            isFirstRender.current = false;
            return;
        }
        console.log('👴 用户年龄变了,请求老年版接口...');
    }, [userInfo.age]); // 👈 只监听 age 字段

    return <div>当前用户:{userInfo.name}</div>;
}

export default App;

监听数组

js
import {useEffect, useRef, useState} from 'react';


function App() {
    const [list, setList] = useState([1, 2, 3]);

    // ✅ 监听数组长度:只要增加或删除元素,就会触发
    useEffect(() => {
        console.log('列表长度变了,当前长度:', list.length);
    }, [list.length]);

    // ✅ 监听特定项:比如只监听第 0 个元素
    // 注意:如果数组可能为空,需要加可选链 ?.
    useEffect(() => {
        console.log('列表的第一项变了:', list[0]);
    }, [list[0]]);

    return <button onClick={() => setList([...list, list.length + 1])}>添加</button>;
}

export default App;

如有转载或 CV 的请标注本站原文地址