【问题标题】:Material UI TextField React Component Conditional style don't trigger textField renderMaterial UI TextField React Component 条件样式不触发 textField 渲染
【发布时间】:2018-03-29 13:27:58
【问题描述】:

反应组件:

class Info extends Component {
    constructor() {
       this.state = {
        editAccount: false
       }
       this.changeTrue = this.changeTrue.bind(this);
       this.changeFalse = this.changeFalse.bind(this);
    }
    changeTrue() {
      this.setState({ediAccount: true}
    }
    changeFalse() {
      this.setState({ediAccount: false}
    }
    render() {
        const specific_style = this.state.editAccount ? { background: 'red'} : { background : 'yellow' }
        return (
         <div>
            <TextField
                id='first_name'
                inputStyle={ specific_style}
                value={this.state.first_name}
              />
           <button onClick={this.changeTrue}>Click True</button>
           <button onClick={this.changeFalse}>Click False</button>
         </div>
        )
    }
}

让这个组件和 editAccount 改变状态不会重新渲染应用样式更改?不重新渲染 TextField 吗?有人知道为什么吗?

【问题讨论】:

  • editAccount 来自哪里? redyellow 应该是字符串。你忘了用/&gt; 关闭你的TextField 组件。请更正这些问题。
  • 您的代码中缺少许多部分。你能发布完整的代码吗?
  • 再次发表评论,因为不确定是代码中的错字还是此处:this.setState({ediAccount: true}

标签: reactjs material-ui


【解决方案1】:

State Updates May Be Asynchronous

React 可以批量处理多个setState() 调用单个更新以提高性能。

因为this.propsthis.state可能会异步更新,所以你 不应依赖它们的值来计算下一个状态。

根据当前状态更新状态时,始终在调用setState() 时使用回调。回调获取上一个状态并返回下一个状态。这是因为 react 可能会批量调用 setState(),因此不使用回调将覆盖以前的调用:

this.setState(prevState => ({editAccount: !prevState.editAccount)});

在您的对象中也包含您使用变量(未定义)而不是字符串的样式:

const specific_style = this.state.editAccount ? { background: red /* red is not defined*/} : { background : yellow /* same here */ };

应该是这样的:

const specific_style = this.state.editAccount ? { background: 'red' } : { background : 'yellow' };

对象不能像 css 类那样编写。

完整的工作代码必须看起来像这样:

class Info extends Component {
  constructor(props) {
    super(props);

    this.state = {
      editAccount: false
    };

    this.changeStyle = this.changeStyle.bind(this);
  }

  changeStyle() {
    this.setState(state => ({editAccount: !state.editAccount}));
  }

  render() {
    const specific_style = this.state.editAccount ? { background: 'red' } : { background: 'yellow' };
    return (
      <div>
        <TextField
          id="first_name"
          inputStyle={specific_style}
        />
        <button onClick={this.changeStyle}>Toggle red/yellow</button>
      </div>
    );
  }
}

看到这个working codesandbox example

【讨论】:

  • 正确和更新状态变化的样式。仍在发生。
  • @NicuIonutCampian 你打电话给setState()时的错字呢?你写的是ediAccount而不是editAccount
  • 我的错误类型会触发我运行时错误,我可以修复它。这不是问题。我查看了 Material-ui 中的 TextField 类,如果样式发生更改,则没有条件重新渲染 TextField 组件。
  • @NicuIonutCampian 不,这个错字不会导致运行时错误。您正在那里设置样式对象的键的名称。您最终将拥有一个带有 ediAccounteditAccount 键的对象,如下所示:{editAccount: false, ediAccount: true}ediAccount 不在任何地方使用。 style 道具也不需要实现。每个 react 组件默认都有它,并且它的更改总是会触发重新渲染。请确保您的代码在此处发布之前不包含任何微不足道的错误。
  • @NicuIonutCampian 我做了一个小的代码和框示例,您可以看到它完美地工作:codesandbox.io/s/oxy0lw75wz。您的代码的另一个问题是您的constructor() 没有使用props 调用super()
【解决方案2】:

您似乎忘记将“”放在渲染函数的返回值中。我们两个人进行了编辑来解决这个问题,但也许这也是问题

【讨论】:

  • 这是一个快速的模拟类实现,组件写得很好。
  • 那么我建议发布一个更完整的实现。
【解决方案3】:

您可能需要使用像 componentWillReceiveProps 这样的生命周期方法来强制重新渲染。另外 - 格式化您的代码

【讨论】:

  • 这对状态变化有何帮助?当 props 或 state 发生变化时,react 不需要强制重新渲染。
【解决方案4】:

editAccount 在哪里/如何定义?它应该来自stateprops 来触发重新渲染。

如果render() 方法不受props / state 更改的影响,则不会触发。

【讨论】:

  • IMO,与其将其作为答案,不如将其作为评论。
  • 触发了重新渲染方法,但 TextField 没有采用新样式。可能 TextField 组件 render() 不会被触发。但为什么呢?
  • @NicuIonutCampian 您在样式对象中使用了未定义的变量redyellow。这应该是字符串'red''yellow' 而不是?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-29
  • 2019-12-18
  • 1970-01-01
  • 2021-09-05
  • 2016-12-21
  • 1970-01-01
相关资源
最近更新 更多