【问题标题】:How do i make my reusable react component saves when the user clicks button?当用户单击按钮时,如何使我的可重用反应组件保存?
【发布时间】:2018-05-19 12:27:41
【问题描述】:

我的组件this.props.save(); 什么时候componentWillUnmount?但是,如果我将页面留在不同选项卡中的外部链接,它不会触发 componentWillUnmount

我的组件

export default class AutoSave extends React.Component {

  constructor(props) {
    super(props);
    this.setIntervalId = null;
  }

  componentDidMount() {
    if (!window.onbeforeunload) {
      window.onbeforeunload = () => {
        this.props.save();
      };
    }

    this.setIntervalId = setInterval(() => this.props.save(), this.props.intervalInMs);
  }

  componentWillUnmount() {
    this.props.save();
    clearInterval(this.setIntervalId);
  }

  render() {

    return <span className="saving">Last saved at {now()}</span>;
  }
}

我的链接是这样的

<Link href="http://www.google.com"  target="_blank">
      Google Link
    </Link> 

当用户点击链接时如何保存组件?这是一个 react/redux 应用程序。

【问题讨论】:

  • 打开新标签不会触发componentWillUnmount()onbeforeunload。在这两种情况下,因为您的应用仍然在原始选项卡中打开。 React 不会在您关闭或离开页面之前立即卸载组件,因此即使页面关闭,componentWillUnmount() 也不会执行任何操作。 onbeforeunload 仅在您从页面在同一选项卡 中导航离开 或关闭选项卡/窗口时触发。如果您想在每次用户单击您的按钮时可靠地调用this.props.save(),那么只需向按钮添加一个onClick 处理程序。
  • 你能告诉我怎么做吗?

标签: javascript reactjs ecmascript-6 redux state


【解决方案1】:

打开新标签不会触发 componentWillUnmount() 或 onbeforeunload。在这两种情况下,因为您的应用仍然在原始选项卡中打开。 React 不会在您关闭或离开页面之前立即卸载组件,因此即使页面关闭,componentWillUnmount() 也不会执行任何操作。 onbeforeunload 仅在您离开同一选项卡中的页面或关闭选项卡/窗口时触发。

如果您想在每次用户单击您的按钮时可靠地调用 this.props.save(),那么只需向按钮添加一个 onClick 处理程序。

render() {
  return <span onClick={this.props.save} className="saving">Last saved at {now()}</span>;
}

【讨论】:

    【解决方案2】:

    你为什么要在一个从“React.Component”扩展而来的类中做某种工作。在 ReactJS 中,组件并不意味着做这样的工作。来自官方文档“组件让您将 UI 拆分为独立的、可重用的部分,并孤立地考虑每个部分。”。除了与 ui 相关的 span 之外,您的组件中没有任何部分。无论如何,您应该将 AutoSave 创建为纯组件并在所有 React 组件中使用它。 :

    export default class AutoSave 
    {
      constructor(saveFn, intervalInMs) {
        this.saveFn = saveFn;
        this.setIntervalId = setInterval(
            () => { 
                this.save();
            }, 
            intervalInMs
        );
      }
    
      unmount() {
        this.save();
        clearInterval(this.setIntervalId);
      }
    
      save() {
        this.saveFn();
        this.callOnSaveCallback();
      }
    
      onSave(callback) {
        this.onSaveCallback = callback;
      }
    
      // private method that calls onSaveCallback
      callOnSaveCallback() {
        if(this.onSaveCallback != null)
            this.onSaveCallback();
      }
    
    }
    

    并像这样在我的 React 组件中使用它:

    import AutoSave from './AutoSave';
    export default class ReactComponent extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                // ... other properties
                "lastSave": new Date()
            }
            this.save = this.save.bind(this);
            this.autoSave = new AutoSave(this.save, 100);
            this.autoSave.onSave(
                () => {
                    this.setState(
                        {
                            "lastSave": new Date()
                        }
                    );
                } 
            )
        }
    
        componentWillUnmount() {
            this.autoSave.unmount();
            this.autoSave = null;
        }  
    
        onClick() {
            this.autoSave.save();
        } 
    
        save() {
            // some saving job
        }
    
        render() {
            return ( 
                <div>
                    // ... other components
                    <Link href="http://www.google.com"  target="_blank" onClick={this.onClick.bind(this)}>
                      Google Link
                    </Link> 
                    <span className="saving">Last saved at {this.state.lastSave}</span>
                </div>
            );
        } 
    }
    

    【讨论】:

    • 如果它是一个反应组件,为什么它会有所作为。我试图在多个地方重用它,而不必重做它在组件内的使用方式?你有什么更新的答案吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    相关资源
    最近更新 更多