簡體   English   中英

將有狀態 React 組件轉換為無狀態功能組件:如何實現“componentDidMount”類型的功能?

[英]Converting stateful React component to stateless functional component: How to implement "componentDidMount" kind of functionality?

我寫了一個小的有狀態的 React 組件。 當這個組件加載時,在componentDidMount方法中,我使用 Kendo UI 在彈出窗口中顯示組件的內容。

這是我的代碼:

export class ErrorDialog extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.errorPopupWindow = null;
    window.addEventListener('resize', this.resizeComponent);
    this.handleWindowKeyDown = this.handleWindowKeyDown.bind(this);
    this.handleButtonCloseWindowOnClick = this.handleButtonCloseWindowOnClick.bind(this);
    this.handleButtonShowDetailsOnClick = this.handleButtonShowDetailsOnClick.bind(this);
    $('#ErrorInformationForm-CloseWindow').focus();
  }

  render() {
    const errorInformation = this.props.errorInformation;
    const baseException = errorInformation.baseException;
    const showExceptionMessage = (typeof baseException !== 'undefined' && typeof baseException === 'object' && baseException !== null
          && typeof baseException.message !== 'undefined' && typeof baseException.message === 'string' && baseException.message !== null
          && baseException.message !== '') ? true : false;
    const baseExceptionMessage = showExceptionMessage ? baseException.message : '';
    const exceptionMessageCss = showExceptionMessage ? 'k-textbox ce-width-100-pct ce-margin-top-5' : 'ce-invisible';
    return(
      <div id="Error-Dialog-Popup" onKeyDown={this.handleWindowKeyDown}>
        <div className="ce-window-body">
          {errorInformation.message}
          <code>
            <textarea readOnly={true} className={exceptionMessageCss} rows="3" defaultValue={baseExceptionMessage} />
          </code>
        </div>
      </div>
    );
  }

  componentDidMount() {
    const errorInformation = this.props.errorInformation;
    const modalWindowTitle = '<span class="ce-width-100-pct ce-app-color-red"><i class="fa ce-fs-1-2-5x fa-times-circle"></i> ' + errorInformation.heading + '</span>';
    $('#Error-Dialog-Popup').kendoWindow({
      actions: [],
      width: 500,
      height: 130,
      visible: true,
      modal: true,
      title: modalWindowTitle,
      resizable: false
    });
    this.resizeComponent();
  }

  resizeComponent() {
  }

  closeWindowIfPossible(evt) {
  }

  handleWindowKeyDown(evt) {
  }

  handleButtonShowDetailsOnClick(evt) {
  }

  handleButtonCloseWindowOnClick(evt) {
  }
}

鑒於此組件不需要維護任何狀態,我正在嘗試將此組件轉換為無狀態功能組件。

我掙扎的地方是如何實現 componentDidMount 功能 這是我到目前為止編寫的代碼:

export const ErrorDialog = (props, context) => {
  const errorInformation = props.errorInformation;
  const baseException = errorInformation.baseException;
  const showExceptionMessage = (typeof baseException !== 'undefined' && typeof baseException === 'object' && baseException !== null
        && typeof baseException.message !== 'undefined' && typeof baseException.message === 'string' && baseException.message !== null
        && baseException.message !== '') ? true : false;
  const baseExceptionMessage = showExceptionMessage ? baseException.message : '';
  const exceptionMessageCss = showExceptionMessage ? 'k-textbox ce-width-100-pct ce-margin-top-5' : 'ce-invisible';

  const resizeComponent = () => {
  }

  const closeWindowIfPossible = (evt) => {
  }

  const handleWindowKeyDown = (evt) => {
  }

  const handleButtonShowDetailsOnClick = (evt) => {
  }

  const handleButtonCloseWindowOnClick = (evt) => {
  }

  const handleComponentOnLoad = (evt) => {
    console.log('comes in onLoad');
    const errorInformation = props.errorInformation;
    const modalWindowTitle = '<span class="ce-width-100-pct ce-app-color-red"><i class="fa ce-fs-1-2-5x fa-times-circle"></i> ' + errorInformation.heading + '</span>';
    $('#Error-Dialog-Popup').kendoWindow({
      actions: [],
      width: 500,
      height: 130,
      visible: true,
      modal: true,
      title: modalWindowTitle,
      resizable: false
    });
    resizeComponent();
  }

  return(
    <div id="Error-Dialog-Popup" onLoad={handleComponentOnLoad} onKeyDown={handleWindowKeyDown}>
      <div className="ce-window-body">
        {errorInformation.message}
        <code>
          <textarea readOnly={true} className={exceptionMessageCss} rows="3" defaultValue={baseExceptionMessage} />
        </code>
      </div>
    </div>
  );
}

起初,我以為我可以在 div 的onLoad事件處理程序中實現componentDidMount類型的功能,但是當我嘗試這樣做時,我注意到該事件根本沒有被觸發(然后我閱讀了文檔並發現我真的不能使用此事件:))。

所以我的問題是:

  • 有沒有辦法在無狀態功能組件中實現componentDidMount類型的功能? 本質上,我需要做的是在組件加載到 DOM 時對其進行處理。
  • 在無狀態功能組件的情況下,我想要做的是一個有效的場景,還是我應該堅持使用標准組件?

功能性無狀態組件沒有生命周期方法。 在這種情況下,您應該堅持使用標准組件。


來自 React 的文檔

這些組件不得保留內部狀態,沒有后備實例,也沒有組件生命周期方法。

他們所說的(上面),但也考慮制作一個有狀態的組件容器並將 props/args 傳遞給無狀態的子組件。

在 React 16.8 中,您現在可以對功能組件使用狀態掛鈎 對於componentDidMount ,建議使用Effect Hooks

import React, { useState, useEffect } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]); // Only re-run the effect if count changes)

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

演示: https : //codepen.io/rjruizes/pen/yLMZPvR

如果您希望 Effect Hook 僅在掛載后運行,請使用空數組作為條件:

useEffect(() => {
  document.title = `You clicked ${count} times`;
}, []);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM