如何在 React 中编辑输入?

How to edit an input in React?

我现在可以专注于输入和修改文本。但是当我按下回车键时,文本根本没有改变。我把代码留在后面。我有一份待办事项清单和一份已完成清单。当我编辑待办事项列表中的文本并按回车键时,修改后的值会出现在我的控制台中,但是当我将待办事项发送到已完成列表时 return 原来的 value/text

import React from "react";
import "../list.css";

class List extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();
    this.state = {
      isEditing: false,
      textInput: this.props.value,
    };
    this.focusTextInput = this.focusTextInput.bind(this);
  }

  focusTextInput() {
    this.textInput.current.focus();
  }

  // handleOnSubmit(event) {
  // event.preventDefault();
  // let aa = this.state.textInput;
  // if (aa !== "") {
  //   this.setState({ items: [...this.props.items, aa] });
  //   console.log(aa);
  // }
  // }

  // componentDidUpdate() {
  //   this.handleOnSubmit();
  // }

  onChange = (event) => {
    // const textInput = this.textInput;
    this.setState({ textInput: event.target.value });
  };

  componentDidMount() {
    const editingState = true;
    if (!this.state.isEditing) {
      this.setState({ isEditing: editingState });
    }
  }

  render() {
    return (
      <ul>
        {this.props.title}
        {this.props.items.map((listItem, index) => {
          return (
            <li id="list-item" key={index}>
              <form onSubmit={(event) => this.onEdit(event)}>
                <input
                  type="text"
                  ref={this.textInput}
                  onChange={(event) => {
                    this.onChange(event);
                  }}
                  defaultValue={listItem}
                />
              </form>
              <button onClick={() => this.props.onAction(listItem)}>
                {this.props.label}
              </button>
              <button onClick={() => this.props.onDeleteItem(listItem)}>
                Delete
              </button>
              <button onClick={() => this.props.onSortItem(listItem)}>
                Sort
              </button>
              <button onClick={() => this.focusTextInput()}>Edit</button>
            </li>
          );
        })}
      </ul>
    );
  }
}

export default List;
import React from "react";
import Form from "./components/Form";
import List from "./components/List";
import "./App.css";

class App extends React.Component {
  state = {
    todoList: [],
    doneList: [],
  };

  addTodo = (value) => {
    if (value !== "") {
      this.setState({ todoList: [...this.state.todoList, value] });
    }
  };

  handleTodo = (value) => {
    const todoList = this.state.todoList.filter(
      (listValue) => listValue !== value
    );
    const doneList = [...this.state.doneList, value];
    this.setState({ todoList, doneList });
  };

  handleDone = (value) => {
    const doneList = this.state.doneList.filter(
      (listValue) => listValue !== value
    );
    const todoList = [...this.state.todoList, value];
    this.setState({ todoList, doneList });
  };

  deleteItem = (value) => {
    const doneList = this.state.doneList.filter(
      (listValue) => listValue !== value
    );
    const todoList = this.state.todoList.filter(
      (listValue) => listValue !== value
    );
    this.setState({ doneList, todoList });
  };

  sortItem = (value) => {
    const todoList = [value].concat(
      this.state.todoList.filter((item) => item !== value)
    );
    this.setState({ todoList });
  };

  editText = (event) => {
    event.preventDefault();
    let aa = this.props.textInput;
    if (aa !== "") {
      this.setState({ todoList: [...this.state.todoList, aa] });
      console.log(aa);
    }
  };

  render() {
    return (
      <div className="App">
        <Form onSubmit={this.addTodo} />
        <List
          onDeleteItem={this.deleteItem}
          onAction={this.handleTodo}
          items={this.state.todoList}
          onSortItem={this.sortItem}
          onEdit={this.editText}
          title="Todo"
          label="Done"
        />
        <List
          onDeleteItem={this.deleteItem}
          onAction={this.handleDone}
          items={this.state.doneList}
          title="Done"
          label="Todo"
        />
      </div>
    );
  }
}

export default App;

快速查看了您的 codesandbox,我认为问题出在您的 List 组件中。在那里,您映射待办事项并提供 index 作为键。我怀疑这是问题所在。

React 使用这个键来优化渲染。这就是 React 可以快速找出哪些组件已更改、添加或删除的方式。当它是静态列表时,idx 很好,因为索引零将始终指向同一组件。但是对于像您这样的流动列表,索引零可能不会指向相同的组件,这使得事情更难遵循。不过,作为最佳实践,最好始终使用唯一键。

为了让它工作,我只使用了 todo 名称,但如果用户能够对多个待办事项使用相同的名称,您可能应该想出别的办法。

您可以在此处阅读有关密钥的更多信息:https://reactjs.org/docs/lists-and-keys.html

我在这里看到 2 个问题。你使用了错误的 key 属性 这使得反应变得奇怪,而且你的方法 onAction 也是错误的,因为你没有以某种方式传递新值。

看看这个沙盒

https://codesandbox.io/s/wizardly-bhaskara-kiwpf

<li id="list-item" key={listItem}>

然后

<button onClick={() => this.props.onAction(listItem, this.state.textInput)}>

handleTodo = (originalValue, newValue) => {
    const todoList = this.state.todoList.filter(
      listValue => listValue !== originalValue
    );

const doneList = [...this.state.doneList, newValue ? newValue : originalValue];
    this.setState({ todoList, doneList });
  };

@Apostolos

https://codesandbox.io/s/wizardly-bhaskara-kiwpf

感谢您的回答,但这似乎无法解决操作问题。当我编辑时,它什么也没做...也许我遗漏了什么。

@nicovg15 这是一个根据您的沙箱进行编辑的工作示例。

https://codesandbox.io/s/adoring-moser-4emfp?file=/src/components/listItem.jsx

映射数据时最好使用新组件。例如,而不是这个

{
  this.props.items.map((listItem, index) => {
    return (
      <li id="list-item" key={index}>
        <form onSubmit={(event) => this.onEdit(event)}>
          <input
            type="text"
            ref={this.textInput}
            onChange={(event) => {
              this.onChange(event);
            }}
            defaultValue={listItem}
          />
        </form>
        <button onClick={() => this.props.onAction(listItem)}>
          {this.props.label}
        </button>
        <button onClick={() => this.props.onDeleteItem(listItem)}>
          Delete
        </button>
        <button onClick={() => this.props.onSortItem(listItem)}>Sort</button>
        <button onClick={() => this.focusTextInput()}>Edit</button>
      </li>
    );
  });
}

这样做

{
  this.props.items.map((listItem, index) => (
    <li key={index}>
      <ListItem listItem={listItem} {...this.props} />
    </li>
  ));
}

这确保您 select 的项目将针对您 select 的项目进行编辑、更新等。

import React from "react";
import List from "./stest";

class App extends React.Component {
  state = {
    todoList: ["Test"],
    doneList: [],
  };

  addTodo = (value) => {
    if (value !== "") {
      this.setState({ todoList: [...this.state.todoList, value] });
    }
  };

  handleTodo = (value) => {
    const todoList = this.state.todoList.filter(
      (listValue) => listValue !== value
    );
    const doneList = [...this.state.doneList, value];
    this.setState({ todoList, doneList });
  };

  handleDone = (value) => {
    const doneList = this.state.doneList.filter(
      (listValue) => listValue !== value
    );
    const todoList = [...this.state.todoList, value];
    this.setState({ todoList, doneList });
  };

  deleteItem = (value) => {
    const doneList = this.state.doneList.filter(
      (listValue) => listValue !== value
    );
    const todoList = this.state.todoList.filter(
      (listValue) => listValue !== value
    );
    this.setState({ doneList, todoList });
  };

  sortItem = (value) => {
    const todoList = [value].concat(
      this.state.todoList.filter((item) => item !== value)
    );
    this.setState({ todoList });
  };

  editText = (event, listItem) => {
    console.log(event.target.value, listItem);
    event.preventDefault();
    let aa = event.target.value;
    let remtodo = this.state.todoList.filter((x) => x !== listItem);
    remtodo.push(aa);
    this.setState({ todoList: [...remtodo] });

    console.log(remtodo);
  };

  render() {
    return (
      <div className="App">
        <List
          onDeleteItem={this.deleteItem}
          onAction={this.handleTodo}
          items={this.state.todoList}
          onSortItem={this.sortItem}
          onEdit={this.editText}
          title="Todo"
          label="Done"
        />
        <List
          onDeleteItem={this.deleteItem}
          onAction={this.handleDone}
          items={this.state.doneList}
          title="Done"
          label="Todo"
        />
      </div>
    );
  }
}

export default App;

import React from "react";


class List extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();
    this.state = {
      isEditing: false,
      textInput: this.props.value,
    };
    this.focusTextInput = this.focusTextInput.bind(this);
  }

  focusTextInput() {
    this.textInput.current.focus();
  }

  // handleOnSubmit(event) {
  // event.preventDefault();
  // let aa = this.state.textInput;
  // if (aa !== "") {
  //   this.setState({ items: [...this.props.items, aa] });
  //   console.log(aa);
  // }
  // }

  // componentDidUpdate() {
  //   this.handleOnSubmit();
  // }

  onChange = (event) => {
    // const textInput = this.textInput;
    this.setState({ textInput: event.target.value });
  };

  componentDidMount() {
    const editingState = true;
    if (!this.state.isEditing) {
      this.setState({ isEditing: editingState });
    }
  }

  render() {
    return (
      <ul>
        {this.props.title}
        {this.props.items.map((listItem, index) => {
          return (
            <li id="list-item" key={index}>
              {/* <form onSubmit={(event) => this.onEdit(event)}> */}
                <input
                  type="text"
                  ref={this.textInput}
                  onChange={(event) => {
                    this.props.onEdit(event,listItem)
                  }}
                  defaultValue={listItem}
                />
              {/* </form> */}
              <button onClick={() => this.props.onAction(listItem)}>
                {this.props.label}
              </button>
              <button onClick={() => this.props.onDeleteItem(listItem)}>
                Delete
              </button>
              <button onClick={() => this.props.onSortItem(listItem)}>
                Sort
              </button>
              <button onClick={() => this.focusTextInput()}>Edit</button>
            </li>
          );
        })}
      </ul>
    );
  }
}

export default List;


Edit event has issue. I have changed and tested edit with test value.