表单与状态管理

表单与状态管理

  1. 使用 useState 初始化状态

    • 可以通过 useState 将数据存储在组件的状态中,例如将笔记数组存储在 notes 状态中。

    • 初始值可以通过 props 传递,也可以直接设置为空数组等默认值。

    • 示例:

      javascript 复制代码
      const [notes, setNotes] = useState(props.notes);
  2. 受控组件(Controlled Component)

    • 通过将输入框的 value 属性绑定到组件的状态(如 newNote),实现对输入框的控制。

    • 需要为输入框添加 onChange 事件处理函数,将输入框的值同步到组件状态中。

    • 示例:

      javascript 复制代码
      const [newNote, setNewNote] = useState('');
      const handleNoteChange = (event) => {
        setNewNote(event.target.value);
      };
      <input value={newNote} onChange={handleNoteChange} />;
  3. 表单提交

    • 为表单添加 onSubmit 事件处理函数,防止默认提交行为(event.preventDefault())。

    • 在提交时,可以根据状态创建新对象(如笔记对象),并更新状态。

    • 示例:

      javascript 复制代码
      const addNote = (event) => {
        event.preventDefault();
        const noteObject = {
          content: newNote,
          date: new Date().toISOString(),
          important: Math.random() < 0.5,
          id: notes.length + 1,
        };
        setNotes(notes.concat(noteObject));
        setNewNote('');
      };
      <form onSubmit={addNote}>...</form>;

数据过滤与显示

  1. 条件显示数据

    • 通过添加一个状态(如 showAll)来控制显示的数据。

    • 使用条件运算符(? :)或数组的 filter 方法来筛选数据。

    • 示例:

      javascript 复制代码
      const [showAll, setShowAll] = useState(true);
      const notesToShow = showAll ? notes : notes.filter(note => note.important);
  2. 切换显示状态

    • 通过按钮点击事件更新状态,从而切换显示的内容。

    • 示例:

      javascript 复制代码
      <button onClick={() => setShowAll(!showAll)}>
        show {showAll ? 'important' : 'all'}
      </button>;

练习:电话簿应用

  1. 添加名字

    • 使用受控组件管理输入框,通过表单提交将名字添加到电话簿中。

    • 示例:

      javascript 复制代码
      const [persons, setPersons] = useState([{ name: 'Arto Hellas' }]);
      const [newName, setNewName] = useState('');
      const addPerson = (event) => {
        event.preventDefault();
        const personObject = { name: newName, id: persons.length + 1 };
        setPersons(persons.concat(personObject));
        setNewName('');
      };
  2. 防止重复添加

    • 在添加名字前,检查电话簿中是否已存在该名字。

    • 如果存在,使用 alert 提示用户。

    • 示例:

      javascript 复制代码
      const addPerson = (event) => {
        event.preventDefault();
        if (persons.some(person => person.name === newName)) {
          alert(`${newName} is already added to phonebook`);
        } else {
          const personObject = { name: newName, id: persons.length + 1 };
          setPersons(persons.concat(personObject));
          setNewName('');
        }
      };
  3. 添加电话号码

    • 为表单添加第二个输入框,用于输入电话号码。

    • 示例:

      javascript 复制代码
      const [newNumber, setNewNumber] = useState('');
      const addPerson = (event) => {
        event.preventDefault();
        const personObject = { name: newName, number: newNumber, id: persons.length + 1 };
        setPersons(persons.concat(personObject));
        setNewName('');
        setNewNumber('');
      };
  4. 搜索功能

    • 添加一个搜索输入框,用于按名字过滤电话簿。

    • 使用 filter 方法实现大小写不敏感的搜索。

    • 示例:

      javascript 复制代码
      const [searchTerm, setSearchTerm] = useState('');
      const personsToShow = persons.filter(person =>
        person.name.toLowerCase().includes(searchTerm.toLowerCase())
      );
  5. 组件拆分与重构

    • 将应用拆分为多个独立组件,如搜索框、添加表单、人员列表等。

    • 在根组件中维护状态和事件处理函数。

    • 示例:

      javascript 复制代码
      const App = () => {
        return (
          <div>
            <h2>Phonebook</h2>
            <Filter ... />
            <PersonForm ... />
            <Persons ... />
          </div>
        );
      };

调试与工具

  1. React DevTools

    • 使用 React DevTools 查看组件的状态和属性,方便调试。
    • 可以直接在 DevTools 中修改状态,观察应用的变化。
  2. 调试输出

    • 在组件中临时渲染状态或其他变量,方便调试。

    • 示例:

      javascript 复制代码
      <div>debug: {newName}</div>;

注意事项

  • 状态更新的不可变性
    • 在 React 中,状态更新必须是不可变的,不能直接修改原始状态。
    • 使用数组的 concat 或对象的展开运算符等方法来创建新状态。
  • 表单默认行为
    • 表单提交时会触发页面刷新,需要通过 event.preventDefault() 阻止默认行为。
  • 组件定义位置
    • 不要在另一个组件的定义中直接定义子组件,避免因作用域或生命周期问题导致错误。
相关推荐
维克兜率天10 分钟前
【维克】通道突破:画出趋势的“轨道线“
前端·数据库·人工智能
Ai-_Man11 分钟前
从聊天框到正式文档:AI导出鸭瞄准AI大模型应用的“最后一公里”
开发语言·前端·javascript·人工智能·小程序
乌暮20 分钟前
拆解网页的底层逻辑:用费曼学习法讲透 HTML 与 CSS
前端·css·学习·html
陈随易10 小时前
bm2,Node.js 与 Bun 项目部署新选择
前端·后端·程序员
福兮说11 小时前
canvas 旋转图片的六个坑:四角被裁、Math.ceil 多出 1px 黑边、JPG 角发黑、翻转方向反了
前端·javascript·图像处理·canvas
传人once13 小时前
多图片上传预览功能如何写
前端·css·html·jquery·html5
Eric.4613 小时前
Wan‑Animate+MiniMax-H3 本地部署 AI 漫剧流水线:8G 显存动作迁移与动态分镜工程实战
前端·人工智能·comfyui·ai漫剧
库拉镜像AI牛牛15 小时前
短剧内容自动化生产:知漫剧工作室落地教程
大数据·服务器·前端·人工智能·语音识别
律宏阔15 小时前
Flutter 列表图片内存优化:CachedNetworkImage 与 ClipRRect 的取舍
前端·flutter
行者全栈架构师15 小时前
【鸿蒙心迹】相册文搜图工程化落地:HarmonyOS 7.0 端侧 AI 检索全链路实战与 5 个踩坑解法
前端