首页 > 解决方案 > React:在工作时更改按钮文本

问题描述

在我的React应用程序中,我想要一个通常显示的按钮,单击时Save将其文本更改为,并在保存完成后将其Saving...更改回。Save

这是我的第一次尝试:

import React from 'react';
import { Button } from 'react-bootstrap';

class SaveButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isSaving : false };
    this.onClick = this.onClick.bind(this);
  }

  onClick() {
    // DOES NOT WORK
    this.setState({ isSaving : true });
    this.props.onClick();
    this.setState({ isSaving : false });
  }

  render() {
    const { isWorking } = this.state;
    return (
      <Button bsStyle="primary"
              onClick={isWorking ? null : this.onClick}>
        {isWorking ? 'Saving...' : 'Save'}
      </Button>
    );
  }
}

export default SaveButton;

这不起作用,因为setStatethis.props.onClick()(由父组件传入)都是异步执行的,所以调用会立即返回,并且更改state可能会在 React 优化中丢失(并且可能只会在几毫秒内可见... )。

我阅读了组件状态并决定将状态提升到它所属的位置,父组件,更改按钮保存的表单(在我的应用程序中,它是一个遥远的祖先而不是父级)。所以我isSaving从中删除SaveButton,替换

const { isWorking } = this.state;

经过

const { isWorking } = this.props.isWorking;

并尝试在表单父组件中设置状态。然而,这可能在架构上更干净,但基本上只是将我的问题转移到其他地方:

实际的保存功能是在应用程序中完全不同的位置完成的。为了触发它,我将onClick事件处理程序作为道具传递给组件树;单击按钮后调用链备份该树的工作原理。但是我如何通知相反方向的动作完成,即在树下?

我的问题:如何通知保持状态的表单组件保存已完成?

表单的父组件(知道保存完成)可以使用ref,但不仅有其中一个表单,还有整个数组。

我是否必须设置一个参考列表,每个表单一个?
或者这是否适合转发 refs的情况?

非常感谢您的考虑!:-)

标签: javascriptreactjs

解决方案


这不起作用,因为 setState 和 this.props.onClick() (由父组件传入)都是异步执行的,因此调用会立即返回,并且在 React 优化中可能会丢失对状态的更改

setState一旦状态更新,可以通过回调通知您,因此您可以:

onClick() {
    this.setState({ isSaving : true }, () => {
       this.props.onClick();
       this.setState({ isSaving : false });
    }); 
}

如果this.props.onClick()也是异步的,把它变成一个promise:

onClick() {
    this.setState({ isSaving : true }, () => {
       this.props.onClick().then(() => {
         this.setState({ isSaving : false });
       });
    }); 
}

推荐阅读