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

React中从state取数据并编辑表单元素的问题求助

Let's break down and fix the issues you're facing step by step:

1. First Critical Bug: Missing Return in map (App Component)

In your App component's render method, the map function doesn’t return the <Todo> component. That means none of your Todo items are actually rendered to the DOM—so clicking the button does nothing at all. Fix this by adding a return (or using implicit return with parentheses):

// In App's render method
{this.state.todos.map((todo, index) => {
  return <Todo key={index} index={index} toggle={this.toggle} todo={todo} currentEditIndex={this.state.index} updateTodo={this.updateTodo} />
})}

2. Fix the Editing State Logic

Right now, your global editing state makes all Todo components switch to edit mode when toggled. Instead, we’ll use the stored index in state to target only the clicked Todo for editing:

  • Remove the editing property from App’s state (we don’t need it anymore—index !== null will tell us if we’re in edit mode)
  • In the Todo component, check if its index matches the currentEditIndex from props, instead of relying on a global flag.

3. Replace the Broken update Function with updateTodo

Your original update function references this.state.todo, but your App’s state doesn’t have a todo property. Instead, add a method that updates the specific todo in the todos array using the stored index:

// Add this to your App component
updateTodo = (updatedTodo) => {
  const newTodos = [...this.state.todos];
  newTodos[this.state.index] = updatedTodo;
  this.setState({ todos: newTodos, index: null }); // Reset index to exit edit mode after save
}

4. Simplify the toggle Function

Update the toggle to either set the index to the clicked item, or reset it if we’re already editing that item:

// In App component
toggle = (index) => {
  this.setState(prevState => ({
    index: prevState.index === index ? null : index
  }));
}

5. Update the Todo Component

Modify it to only show the edit form for the currently selected Todo:

class Todo extends Component {
  render() {
    const { index, currentEditIndex, todo, toggle, updateTodo } = this.props;
    
    // Only render EditForm if this todo is the one being edited
    if (currentEditIndex === index) {
      return <EditForm todo={todo} updateTodo={updateTodo} />
    }

    return (
      <li>
        <div>{todo.date}</div>
        <div>{todo.description}</div>
        <button onClick={() => toggle(index)}>Edit</button>
      </li>
    )
  }
}
export default Todo;

6. Fix the EditForm Component

Ensure it correctly initializes state from props and submits changes back to the App:

class EditForm extends Component {
  constructor(props){
    super(props);
    // Handle both Date objects and string dates from props
    const startDate = typeof props.todo.date === 'string' ? new Date(props.todo.date) : props.todo.date;
    this.state = { 
      startDate, 
      description: props.todo.description 
    }
  }

  handleSubmit = (e) => {
    e.preventDefault();
    const updatedTodo = { 
      date: this.state.startDate, 
      description: this.state.description 
    };
    // Call the parent's update method to save changes
    this.props.updateTodo(updatedTodo);
  }

  handleChange = (date) => {
    this.setState({ startDate: date });
  }

  updateDesc = (e) => {
    this.setState({ description: e.target.value });
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <DatePicker 
          selected={this.state.startDate} 
          onChange={this.handleChange} 
          showTimeSelect 
          timeFormat="HH:mm" 
          dateFormat="yy-MM-dd, hh:mm" 
          timeCaption="time" 
        />
        <textarea 
          value={this.state.description} 
          onChange={this.updateDesc} 
        />
        <button type="submit">Save</button>
      </form>
    )
  }
}
export default EditForm;

7. Final Corrected App Component

Here’s the full fixed App component with all changes integrated:

class App extends Component {
  constructor() {
    super();
    this.state = { todos: [], index: null }; // Removed unused "editing" state
  }

  toggle = (index) => {
    this.setState(prevState => ({
      index: prevState.index === index ? null : index
    }));
  }

  createTodo = (todo) => {
    const newArr = [...this.state.todos, todo]; // Simplified array push
    this.setState({ todos: newArr });
  }

  updateTodo = (updatedTodo) => {
    const newTodos = [...this.state.todos];
    newTodos[this.state.index] = updatedTodo;
    this.setState({ todos: newArr, index: null });
  }

  render () {
    return (
      <ul>
        {this.state.todos.map((todo, index) => {
          return (
            <Todo 
              key={index} 
              index={index} 
              toggle={this.toggle} 
              todo={todo} 
              currentEditIndex={this.state.index} 
              updateTodo={this.updateTodo} 
            />
          )
        })}
      </ul>
    );
  }
}
export default App;

Key Fixes Recap:

  • Fixed the missing return in map so Todo components actually render
  • Replaced global edit mode with index-based targeting to only edit the clicked Todo
  • Added a proper updateTodo method to modify the specific todo in the array
  • Corrected date parsing in EditForm to handle both string and Date inputs
  • Ensured the edit form submits changes back to the App and exits edit mode automatically

内容的提问来源于stack exchange,提问作者Umbro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:30:20