React 组件处理 Props

场景一:纯派生数据(只读展示)

使用场景 :根据 props 计算过滤、排序、格式化后的数据,仅用于展示。

设计原则 :不存入 state,直接在渲染时计算。计算量大时用缓存。

不使用缓存(简单场景)

javascript 复制代码
// 函数组件
function ActiveUsers({ users }) {
  const activeUsers = users.filter(u => u.active);   // 每次渲染都执行
  return <ul>{activeUsers.map(...)}</ul>;
}

// 类组件
class ActiveUsers extends React.Component {
  render() {
    const activeUsers = this.props.users.filter(u => u.active); // 每次渲染都执行
    return <ul>{activeUsers.map(...)}</ul>;
  }
}

使用缓存(昂贵计算场景)

javascript 复制代码
// 函数组件(useMemo)
import { useMemo } from 'react';

function ExpensiveProcess({ data }) {
  const processed = useMemo(() => {
    return data.filter(u => u.active).sort(...).map(...); // 昂贵操作
  }, [data]);
  return <div>{processed}</div>;
}

// 类组件(memoize-one)
import memoize from 'memoize-one';

class ExpensiveProcess extends React.Component {
  getProcessed = memoize((data) => {
    return data.filter(u => u.active).sort(...).map(...);
  });
  render() {
    const processed = this.getProcessed(this.props.data);
    return <div>{processed}</div>;
  }
}

场景二:初始值一次性使用(内部状态独立)

使用场景props 作为内部状态的初始值,后续用户可修改,父组件再改 prop 也不覆盖用户输入(如表单)。

设计原则 :仅在初始化时读取 props,不监听后续变化。

javascript 复制代码
// 函数组件
function NameInput({ initialName }) {
  const [name, setName] = useState(initialName);
  return <input value={name} onChange={(e) => setName(e.target.value)} />;
}

// 类组件
class NameInput extends React.Component {
  state = { name: this.props.initialName };
  handleChange = (e) => this.setState({ name: e.target.value });
  render() {
    return <input value={this.state.name} onChange={this.handleChange} />;
  }
}

场景三:响应 Props 变化(重置状态 / 执行副作用)

使用场景

  • 外部数据变化(如 listuserId)需要重置内部状态(页码、选中项)。
  • 需要发起网络请求或操作 DOM。

设计原则 :用 useEffect(函数组件)或 componentDidUpdate(类组件)监听相关 prop,执行更新。

javascript 复制代码
// 函数组件
function UserPanel({ userId }) {
  const [page, setPage] = useState(1);
  const [data, setData] = useState(null);

  useEffect(() => {
    setPage(1);
    fetch(`/api?userId=${userId}`).then(res => res.json()).then(setData);
  }, [userId]);

  return <div>{data}</div>;
}

// 类组件
class UserPanel extends React.Component {
  state = { page: 1, data: null };

  componentDidUpdate(prevProps) {
    if (prevProps.userId !== this.props.userId) {
      this.setState({ page: 1 });
      fetch(`/api?userId=${this.props.userId}`)
        .then(res => res.json())
        .then(data => this.setState({ data }));
    }
  }

  render() {
    return <div>{this.state.data}</div>;
  }
}

快速决策

你的需求 对应场景
只根据 props 算个新值来显示 场景一
初始值来自 props,用户可改,父组件再改 props 不影响 场景二
props 一变,内部状态就要重置 / 发起请求 场景三
相关推荐
gis开发之家40 分钟前
《Vue3 从入门到大神29篇》单元测试与 E2E 测试 —— 保障 Vue3 项目的质量
前端·javascript·vue.js·单元测试·前端框架·vue3
爱勇宝1 小时前
AI 时代,更稀缺的是「提出好问题」还是「判断好答案」?
前端·人工智能·后端
李伟_Li慢慢1 小时前
three.js 中的WebGPU 有几成熟了?
前端·three.js
阿酷tony1 小时前
纯HTML5播放器带倍速、带画质切换的播放器
前端·html·html5
ShiXZ2131 小时前
指令集-NPM 常用指令速查手册
前端·npm·node.js
এ慕ོ冬℘゜1 小时前
前端核心知识体系进阶:从安全机制、网络协议到原生 JS 实战全解析
前端·网络协议·安全
前端H1 小时前
Biome & Rolldown:Rust 工具链接管前端基建
开发语言·前端·rust
forever_world1 小时前
# 💧 从前端视角,彻底搞懂 AI 流式输出 —— 从"接根水管"到 Vue 3 实战
前端·vue.js
灯澜忆梦1 小时前
GO---map函数
开发语言·前端·后端·golang
李剑一1 小时前
uni-app x 实现本地 JSON 文件的导入导出(APP端可用)
android·前端·uni-app