javascript - 如果在 DOM 中手动编辑了文本节点,如何强制 React 更新它?

标签 javascript reactjs

我有一个正在 DOM 中手动编辑的文本节点,当调用 render() 方法时,React 不会更新该文本节点。

使用官方React website中的示例进行演示:

class TodoApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = { items: [], text: '' };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  render() {
    return (
      <div>
        <h3>TODO</h3>
        <TodoList items={this.state.items} />
        <form onSubmit={this.handleSubmit}>
          <label htmlFor="new-todo">
            What needs to be done?
          </label>
          <input
            id="new-todo"
            onChange={this.handleChange}
            value={this.state.text}
          />
          <button>
            Add #{this.state.items.length + 1}
          </button>
        </form>
      </div>
    );
  }

  handleChange(e) {
    this.setState({ text: e.target.value });
  }

  handleSubmit(e) {
    e.preventDefault();
    if (this.state.text.length === 0) {
      return;
    }
    const newItem = {
      text: this.state.text,
      id: Date.now()
    };
    this.setState(state => ({
      items: state.items.concat(newItem),
      text: ''
    }));
  }
}

class TodoList extends React.Component {
  render() {
    return (
      <ul>
        {/* Note: using contentEditable only for the purpose of this demo */}
        {this.props.items.map(item => (
          <li key={item.id} contentEditable={true}>{item.text}</li>
        ))}
      </ul>
    );
  }
}

ReactDOM.render(
  <TodoApp />,
  document.getElementById('todos-example')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="todos-example"></div>

我仅为此演示添加了 contentEditable (我不是试图更新待办事项),当您添加一个新项目,然后直接在 DOM 中编辑它,然后添加另一个项目时项目,为什么之前编辑的项目没有更新到之前的状态?

编辑:

我为什么要这样做? 我有一个应用程序,用户可以单击编辑按钮并开始直接编辑文本,我添加 contentEditable 属性并使用 onInput 存储编辑的文本并更新使用作为 prop 传递的函数的父状态,我想要解决的是当用户取消编辑时,我想恢复之前的文本,我当前正在做的是直接编辑 innerText该元素的值设置先前的值,因为它没有被 React 更新。

最佳答案

你遇到这个问题是因为 React 有一个虚拟 DOM,它可以在其中比较更改。当您修改真实 DOM 时,React 不知道您修改了它,因此当它将其虚拟 DOM 与新的 render() 进行比较时,发现该元素没有任何变化,因此不会重新渲染.

如果您可以控制 React 组件中的所有 HTML,请不要直接修改 DOM,永远不要。您应该在用户操作(在本例中为按键)上添加事件监听器以捕获它们并相应地更新组件状态。如果您这样做,您必须了解如何React virtual DOM works .

关于javascript - 如果在 DOM 中手动编辑了文本节点,如何强制 React 更新它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60929947/

相关文章:

javascript - 从指定范围创建一个字符数组

reactjs - 为什么 React 在重新渲染之前不比较 Previous State 和 New State?为什么调用setState时总是渲染?

javascript - 使用路由器通过路径 react 传递参数并且无法正确呈现

javascript - 使用 sqlite 和 Expo 从 SQL 查询中获取实际的行数组

javascript - 实现 slider 的范围与数字输入绑定(bind)

javascript - 使 Meteor.methods 同步和异步

javascript - 如何将 javascript 对象传递给 VueJS 中的组件?

reactjs - 作为别名导入时的不变违规

javascript - 使用 ng-repeat 从对象属性中的数组访问项目

php - 将数组从 Javascript 发送到 PHP