You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React新手求助:表单提交更新数据后有序列表未同步显示问题

解决React表单提交后列表不更新的问题

Hey there! I see the issue you're facing—you're updating the hobbies.json data directly, but React isn't picking up that change to re-render your list. Let's break down why this happens and fix it step by step.

问题根源

  1. 静态JSON文件不会触发重渲染: 你导入的hobbies.json是静态资源,直接调用hobbies.push(...)修改它不会让React知道数据变了。React只有在组件的state或props更新时才会重新渲染。
  2. 组件间数据不共享: FormHobbies和ListHobbies各自导入了一份hobbies的副本,所以修改Form里的副本对List组件完全没有影响。

解决方案:状态提升 + 受控状态管理

我们需要把共享的hobbies状态提升到父组件App.js,让两个子组件通过props来访问和修改这份数据,这样任何修改都会同步到两个组件。

1. 修改App.js

把hobbies的状态放在这里,同时创建一个添加新爱好的方法,传递给子组件:

import { useState } from 'react';
import FormHobbies from './FormHobbies';
import './css/formhobbies.css';
import ListHobbies from './ListHobbies';
import initialHobbies from './data/hobbies.json';

function App() {
  // 用useState管理爱好列表,初始值来自json文件
  const [hobbies, setHobbies] = useState(initialHobbies);

  // 定义添加新爱好的方法
  const addHobby = (newHobby) => {
    // 不要直接修改原数组,用扩展运算符创建新数组(React需要引用变化来检测更新)
    setHobbies(prevHobbies => [...prevHobbies, newHobby]);
  };

  return (
    <div>
      {/* 把addHobby方法传递给Form组件 */}
      <FormHobbies addHobby={addHobby} />
      {/* 把最新的hobbies数组传递给List组件 */}
      <ListHobbies hobbies={hobbies} />
    </div>
  );
}

export default App;

2. 修改FormHobbies.js

不再直接修改导入的json,而是调用父组件传递来的addHobby方法:

import { useState } from "react";

function FormHobbies({ addHobby }) { // 接收父组件的addHobby方法
  const [nameHobby, setNameHobby] = useState("");
  const [emojiName, setEmojiName] = useState("");

  const onChangeNameHandler = (event) => {
    setNameHobby(event.target.value);
  };

  const onChangeEmojiHandler = (event) => {
    setEmojiName(event.target.value);
  };

  const onSubmit = (event) => {
    event.preventDefault();
    // 创建新的爱好对象,调用addHobby更新父组件状态
    const newHobby = { 
      "Name of Hobbies": nameHobby, 
      Emoji: emojiName 
    };
    addHobby(newHobby);
    emptyValues();
  };

  const emptyValues = () => {
    setNameHobby("");
    setEmojiName("");
  };

  return (
    <div id="formTopLevel">
      <form onSubmit={onSubmit}> {/* 把onSubmit绑定到form的onSubmit事件,比绑定button更规范 */}
        <div id="formSecondLevel">
          <label id="labelOne">Please key in Your Hobbies</label>
          <input
            id="inputOne"
            type="text"
            onChange={onChangeNameHandler}
            maxLength="100"
            name="hobbies"
            placeholder="Type your hobbies"
            value={nameHobby} {/* 把input变成受控组件,绑定state值 */}
          ></input>
          <label id="labelTwo">Please key in Your Emoji</label>
          <input
            id="inputTwo"
            onChange={onChangeEmojiHandler}
            type="text"
            maxLength="100"
            name="emoji"
            placeholder="Type the emoji"
            value={emojiName} {/* 受控组件绑定state */}
          ></input>
          <button type="submit">Submit</button> {/* 明确设置type为submit */}
        </div>
      </form>
    </div>
  );
}

export default FormHobbies;

这里额外做了两个优化:

  • 把表单的onSubmit事件绑定到<form>标签上(这是更标准的做法)
  • 把输入框改成受控组件,绑定value到state,确保输入框的值和state完全同步

3. 修改ListHobbies.js

不再自己导入json,而是使用父组件传递来的hobbies props:

import React from "react";

const ListHobbies = ({ hobbies }) => { // 接收父组件的hobbies数组
  return (
    <div>
      <ol>
        {hobbies.map((hobby, index) => (
          <li key={index}> {/* 注意:如果以后有唯一id,最好用id当key,index只是临时方案 */}
            {hobby["Name of Hobbies"]} {hobby.Emoji}
          </li>
        ))}
      </ol>
    </div>
  );
};

export default ListHobbies;

为什么这样能解决问题?

  • 现在hobbies状态由App.js的useState管理,每次调用setHobbies都会触发App组件重新渲染,进而传递最新的hobbies给ListHobbies,让列表更新。
  • 两个子组件共享同一份数据源,避免了各自持有副本的问题。
  • 受控组件确保输入框的状态完全由React管理,避免了潜在的状态不一致问题。

内容的提问来源于stack exchange,提问作者Theow Meng Ang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 13:33:11