【问题标题】:ReactJs changed state not showReactJs 改变状态不显示
【发布时间】:2020-01-09 22:49:03
【问题描述】:

在线演示:codesandbox.io

reactsemantic-ui 一起使用

说明

我制作了一个名为Alert 的组件包含semantic-ui modal,我在单击页面中的按钮时调用此模式,此模式包含input,它有两个handler,两者似乎都有效,因为我使用console.log 进行调试,所以它在后台工作但不显示更改,最好说state 更改后直到我关闭modal 并再次打开才会显示。

代码查看:

当我点击按钮时,通过这个处理程序调用模态:

this.state = {
...
   amount: 50000
}

Increase = (e) => {
    let Html = (<div><Input value={this.state.amount} onChange={this.handleChange} onBlur={this.handleBlur}/></div>)
    let obj = {
        size: 'tiny',
        content: Html,
    }

    this.setState({
        alertOpen: true,
        alert: obj
    })
}

如您所见,它有两个处理程序,onChangeonBlur;现在模态已打开,值为50000(它设置为默认状态),我想更改输入值,但它不会更改,不可编辑,但在控制台中返回更改的值,现在如果我关闭modal 和再次打开,它显示出新的价值。 onblur 也一样。

handleChange = (e) => {
    let v = e.target.value;
    console.log(v)
    this.setState({
        amount: v
    })
}

handleBlur = (e) => {
    let v = e.target.value;
    console.log(v)
    if(v < 50000){
        this.setState({
            errorMessagePrice: 'Error message!',
            amount: 50000
        })
    }
}

我的看法:

我认为这是因为我试图在另一个组件中更新 state(警报),如果我是对的,我该如何解决这个问题?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    问题在于,当您单击按钮时,您的模态内容创建了一次,但是当 amount 更改时它永远不会更新(因为它正在从状态重新渲染

    最简单的方法是不在状态中存储模态内容,而是在将其传递给模态时生成它。

     <Alert
      size={this.state.alert.size}
      content={
        <div>
          <Input
            value={this.state.amount}
            onChange={this.handleChange}
            onBlur={this.handleBlur}
          />
        </div>
      }
      open={this.state.alertOpen}
      close={this.goClose}
      actions={this.state.alert.actions}
    />
    

    更新的代码笔:https://codesandbox.io/s/semantic-ui-react-fwcfm


    如果您必须保留它在state 中,您应该将其设为函数并在将其传递给模态时调用它(每次都有效地生成它

    更新的代码笔:https://codesandbox.io/s/semantic-ui-react-nqs95

    【讨论】:

    • 您的解决方案非常有效,谢谢,但如果我想采纳您的第一个建议,我的意思是 The easiest way ,当我传递给 modal 时如何生成它?
    • 我认为每次都重新生成内容不是一个好习惯
    • 警报内容应该是动态分配的,我猜。它可以是 Input 元素或 select 元素。无论如何,将警报内容存储为组件状态将是可扩展性的好选择。请告诉我你的想法
    【解决方案2】:

    当然,你可以在每次渲染 Waller 组件时重新生成警报内容,但从性能的角度来看,这并不是最好的解决方案。我认为解决方案是在调用 handleChange 或 handleBlur 时更新警报内容状态。这样,我们就可以只在需要更新的时候才更新提醒内容。

    请查看this code

    【讨论】:

    • 我们可以使用 React Hook 将这个组件写成函数组件。在这种情况下,React.useMemo 将用于避免不必要的重新生成。
    【解决方案3】:

    Component 未重新渲染以显示更新状态的原因是因为您的 input 元素位于 React 无法跟踪的函数中。

    移动此代码

    <div>
            <Input
              value={this.state.amount}
              onChange={this.handleChange}
              onBlur={this.handleBlur}
            />
          </div>
    

    进入waller 的渲染函数,它会正确更新。像这样:

              <Alert
              size={this.state.alert.size}
              content={this.state.alert.content}
              open={this.state.alertOpen}
              close={this.goClose}
              actions={this.state.alert.actions}
            />
            <Input
              value={this.state.amount}
              onChange={this.handleChange}
              onBlur={this.handleBlur}
            />
            <Button onClick={this.Increase}>Increase</Button>
    

    【讨论】:

    • 那么解决办法是什么?
    • 我已经告诉过你,将你的输入元素移到渲染函数中。
    • 不,我不能将输入移动到警报,因为警报是全局组件,内容是动态的
    • 不要移到alert,移到waller的渲染函数中。我编辑了我的评论,使其更加明确
    • 哦,我明白了,让我试试
    【解决方案4】:

    这是将 Jsx 分配为变量的正确方法

    renderSomeJSX() {
    return <Jsx />;
    }
    
    render() {
     retrun (
        < />
         {//use the method as a variable be calling it}
         {this.renderSomeJSX()}
     )}}
    

    您没有在输入变量中使用 return 语句。

    这是使用 props 从子组件设置状态的方法

    this.props.stateAction()
    

    在父组件中

    stateAction = () => {
    this.setState({var:value})
    }
    

    因为你说“因为我试图更新另一个组件中的状态(警报),如果我是对的,我该如何解决这个问题?”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      • 2018-11-06
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多