React中的input defaultValue不会随着state更新而更新。

12 浏览
0 Comments

React中的input defaultValue不会随着state更新而更新。

我正在尝试使用React创建一个简单的表单,但是在将数据正确地绑定到表单的defaultValue时遇到了困难。

我要实现的行为是:

  1. 当我打开我的页面时,文本输入字段应该填写我的数据库中的AwayMessage文本。即为“示例文本”。
  2. 如果我的数据库中的AwayMessage没有文本,我希望Text输入字段中有一个占位符。

然而,现在,每次我刷新页面时,Text输入字段都为空。(尽管我键入的输入可以正确保存和持久化。)我认为这是因为当AwayMessage是一个空对象时,输入文本字段的html会加载,但当awayMessage加载时不会刷新。另外,我无法为该字段指定一个默认值。

出于清晰明了的原因,我删除了一些代码(例如 onToggleChange)。

    window.Pages ||= {}
    Pages.AwayMessages = React.createClass
      getInitialState: ->
        App.API.fetchAwayMessage (data) =>
        @setState awayMessage:data.away_message
        {awayMessage: {}}
      onTextChange: (event) ->
        console.log "VALUE", event.target.value
      onSubmit: (e) ->
        window.a = @
        e.preventDefault()
        awayMessage = {}
        awayMessage["master_toggle"]=@refs["master_toggle"].getDOMNode().checked
        console.log "value of text", @refs["text"].getDOMNode().value
        awayMessage["text"]=@refs["text"].getDOMNode().value
        @awayMessage(awayMessage)
      awayMessage: (awayMessage)->
        console.log "I'm saving", awayMessage
        App.API.saveAwayMessage awayMessage, (data) =>
          if data.status == 'ok'
            App.modal.closeModal()
            notificationActions.notify("Away Message saved.")
            @setState awayMessage:awayMessage
      render: ->
        console.log "AWAY_MESSAGE", this.state.awayMessage
        awayMessageText = if this.state.awayMessage then this.state.awayMessage.text else "Placeholder Text"
        `

Away Messages

AwayMessage 的console.log显示如下:

AWAY_MESSAGE Object {}
AWAY_MESSAGE Object {id: 1, company_id: 1, text: "Sample Text", master_toggle: false}

admin 更改状态以发布 2023年5月20日
0
0 Comments

defaultValue只用于初始加载

如果您想要初始化输入,那么应该使用defaultValue,但是如果您想要使用状态来改变值,则需要使用value。个人而言,如果我只是要初始化它,那么我喜欢只使用defaultValue,然后在提交时使用引用(refs)获取值。在React文档的https://facebook.github.io/react/docs/forms.htmlhttps://facebook.github.io/react/docs/working-with-the-browser.html上有更多关于引用和输入的信息。

以下是我如何重新编写您的输入框:

awayMessageText = if this.state.awayMessage then this.state.awayMessage.text else ''

此外,您不想像您所做的那样传递占位符文本,因为那样会将值设置为“占位符文本”。您仍然需要将空值传递到输入框,因为未定义(undefined)和空值(nil)本质上是将value转换为defaultValue。请参见https://facebook.github.io/react/tips/controlled-input-null-value.html

getInitialState无法进行API调用

必须在运行getInitialState之后进行API调用,对于您的情况,我会在componentDidMount中执行。请参照此示例:https://facebook.github.io/react/tips/initial-ajax.html

我还建议您阅读有关React组件生命周期的文档。请参阅https://facebook.github.io/react/docs/component-specs.html

带修改和加载状态的重写

个人而言,我不喜欢在渲染中使用if else逻辑,而是更喜欢在我的状态中使用“loading”,并在表单加载之前渲染一个FontAwesome旋转器,http://fortawesome.github.io/Font-Awesome/examples/。以下是一种重写方式,以向您展示我的意思。如果我弄错了cjsx的勾选框,那是因为我通常会像这样使用coffeescript,.

window.Pages ||= {}
Pages.AwayMessages = React.createClass
  getInitialState: ->
    { loading: true, awayMessage: {} }
  componentDidMount: ->
    App.API.fetchAwayMessage (data) =>
      @setState awayMessage:data.away_message, loading: false
  onToggleCheckbox: (event)->
    @state.awayMessage.master_toggle = event.target.checked
    @setState(awayMessage: @state.awayMessage)
  onTextChange: (event) ->
    @state.awayMessage.text = event.target.value
    @setState(awayMessage: @state.awayMessage)
  onSubmit: (e) ->
    # Not sure what this is for. I'd be careful using globals like this
    window.a = @
    @submitAwayMessage(@state.awayMessage)
  submitAwayMessage: (awayMessage)->
    console.log "I'm saving", awayMessage
    App.API.saveAwayMessage awayMessage, (data) =>
      if data.status == 'ok'
        App.modal.closeModal()
        notificationActions.notify("Away Message saved.")
        @setState awayMessage:awayMessage
  render: ->
    if this.state.loading
      ``
    else
    `
         

Away Messages

这大约就是它的全部。现在使用状态和值的表单的其中一种方式就是这样。您还可以只使用defaultValue而不是value,然后在提交时使用引用(refs)来获取值。如果您走这条路线,我建议您有一个外壳组件(通常称为高阶组件)来获取数据,然后将其作为props传递给表单。

总的来说,我建议您彻底阅读React文档并进行一些教程。有很多博客,http://www.egghead.io有一些很好的教程。我的网站上也有一些内容,http://www.openmindedinnovations.com

0
0 Comments

修复此问题的另一种方法是更改输入的


更新:
由于此内容得到了支持,我必须说在内容加载时应该正确地使用 disabledreadonly 属性,以免降低用户体验。

是的,这很可能是一种方法,但它完成了工作.. 😉

0