如何使 React 组件可编辑?

Al-*_*l-m 5 javascript edit firebase reactjs

在我学习 react 和 firebase 项目的最后阶段,我遇到了一个问题。通过阅读这两个的文档,我已经了解了在大多数情况下如何以及如何做。

我想从博客文章中获取内容,然后对其进行编辑并使用

update()
Run Code Online (Sandbox Code Playgroud)

方法 firebase 有。到目前为止,我面临的两个错误是我无法编辑该内容,因为 react 说它是一个受控元素,我从文档中了解到这是因为我将其作为值传入。

但是,当我尝试删除它并在 onInputChange 中创建一个 setState 时,就像文档建议的那样,它已更新但内容为空白,并且输入字段中也缺少原始文本。这意味着我在反应时做错了但我不确定它是什么。

这是目前设置代码的方式。问题的摘要归结为为什么我无法更改文本框中的值。请问我做错了什么?

Jos*_*man 5

如果您想在 React 中创建可编辑的受控输入,请创建带有值的输入以及更改该值的方法:

<input
 type="text"
 value={this.state.title}
 onChange={e => this.handleInputChange(e)}
/>
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,您定义了一对 onChange 处理程序,但您没有将事件传递给它们,因此它们永远没有任何数据可以使用。

对于我的示例,我的 onChange 处理程序可以是:

handleInputChange(e) {
    this.setState({
      title: e.target.value
    });
  }
Run Code Online (Sandbox Code Playgroud)

每当我输入输入内容时,它都会改变组件的状态,从而改变我在输入中看到的内容。虽然有点间接,但这就是受控组件在 React 中的工作方式。

如果您添加一个新的输入,那么您可以创建一个新的 onChange 处理程序,并且一切都应该正常工作。但这种方法很快就会变得复杂。创建一个包含 10 个输入的表单,突然间您的组件中就有了一大堆需要处理的函数。

更易于管理的方法是创建一个适用于每个输入组件的 onChange 处理程序。您可以通过将要更新的状态字段的名称传递到函数中来创建它。

 handleChange(e, field) {
    this.setState({
      [field]: e.target.value
    });
  }
Run Code Online (Sandbox Code Playgroud)

然后在您的输入中您可以像这样使用它:

<input
          type="text"
          value={this.state.title}
          onChange={e => this.handleChange(e, "title")}
        />
Run Code Online (Sandbox Code Playgroud)

field 参数是您希望该输入更新的状态的字段名称的字符串。

这意味着您可以对正文输入重复使用相同的方法,如下所示:

  type="text"
  value={this.state.body}
  onChange={e => this.handleChange(e, "body")}
/>
Run Code Online (Sandbox Code Playgroud)

可以删除onTitleChange和onBodyChange方法,用上面的handleChange方法替换。简单多了。移动部件越少,损坏的东西就越少。

当您准备好提交表单时,您可以在 onHandleUpdate 方法中使用所需的状态值,如下所示:

onHandleUpdate(e){
    e.preventDefault();
    database.ref('posts').child(`${this.postId}`).update({
       title: this.state.title,
       body: this.state.body
    }); 
    this.setState({
      title: '',
      body: ''    
    });
  }
Run Code Online (Sandbox Code Playgroud)

无需对状态中的后值执行所有嵌套操作。您可以随心所欲地嵌套,但是当您仍在学习时,只需保持尽可能多的非嵌套状态即可使事情易于推理。

database.ref(`posts/${this.props.match.params.postId}`) 
    .on('value', snap =>  this.setState({
       title: snap.val().title, 
       body: snap.val().body 
    }));
Run Code Online (Sandbox Code Playgroud)

我做了一个小沙箱来证明这一切都是有效的。看看这里的 hello 组件。我已经简化了一点,我必须替换数据库调用(因为我没有你的 firebase 密钥),但这应该是有意义的。