【问题标题】:React: triggering method inside HOC componentReact:HOC组件内部的触发方法
【发布时间】:2019-11-24 07:28:47
【问题描述】:

我想要做的是创建一个 HOC,它有一个方法可以由使用该 HOC 进行包装的任何父组件触发。

对于这个 HOC,我正在尝试淡出 HOC 和其中的任何组件:

HOC:

export function fadeOutWrapper(WrappedComponent) {
  return class extends Component {
    constructor(props) {
      super(props);
      this.state = {
        showElement: true,
        removeElement: false,
      };
    }

    _triggerFade = () => {
      this._fadeOut(this.props.time).then(time => this._removeElement(time));
    }

    _fadeOut = time => {
      let _this = this;
      return new Promise((resolve, reject) => {
          _this.setState({
            showElement: false
          });
        setTimeout(() => {
          resolve(time);
        }, time);
      });
    };

    _removeElement = time => {
      let _this = this;
      setTimeout(() => {
        _this.setState({
          removeElement: true
        });
      }, time + 500);
    };

    render() {
      return this.state.removeElement ? null : (
        <div
          className={
            this.state.showElement
              ? "cfd-container"
              : "cfd-container cfd-fadeout"
          }
        >
          <WrappedComponent {...this.props} />
        </div>
      );
    }
  };
}

这个组件是如何在父组件中使用的:

import ComponentToBeFaded from '...';
import { fadeOutWrapper } from '...';

const WrappedComponent = fadeOutWrapper(ComponentToBeFaded);

class ParentComponent extends Component {
 const...
 super...

 handleChildClick = () => {
  // ? how to trigger the HOC _triggerFade method?
  // WrappedComponent._triggerFade()
 }

 render() {
  return (
   <WrappedComponent time={1000} handleClick={this.handleChildClick} {...other props component needs} />
  )
 }
}

我想要做的是调用 HOC 内部的方法,似乎无法检查 HOC 内部 props 的变化......只能在 HOC 的 render() 内部检查

需要继续写更多以满足提交配额。任何关于如何做到这一点的想法表示赞赏。希望你的一天一切顺利!

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    包装组件的本地状态不需要 showElement,因为它不受该组件控制。将其作为 props 传递并使用 componentDidUpdate 开始淡出。

    const { Component, useState, useCallback } = React;
    const Button = ({ onClick }) => (
      <button onClick={onClick}>Remove</button>
    );
    function App() {
      const [show, setShow] = useState(true);
      const onClick = useCallback(() => setShow(s => !s), []);
      return (
        <WrappedButton
          time={1000}
          onClick={onClick}
          showElement={show}
        />
      );
    }
    
    function fadeOutWrapper(WrappedComponent) {
      return class extends Component {
        constructor(props) {
          super(props);
          this.state = {
            removeElement: false,
            fadeout: false,
          };
        }
        componentDidUpdate(prevProps) {
          if (
            this.props.showElement !== prevProps.showElement &&
            !this.props.showElement
          ) {
            this._triggerFade();
          }
        }
        _triggerFade = () => {
          this._fadeOut(this.props.time).then(() =>
            this._removeElement()
          );
        };
    
        _fadeOut = time => {
          this.setState({ fadeout: true });
          return new Promise(resolve => {
            setTimeout(() => {
              resolve();
            }, time);
          });
        };
    
        _removeElement = time => {
          this.setState({
            removeElement: true,
          });
        };
    
        render() {
          return this.state.removeElement ? null : (
            <div>
              {JSON.stringify(this.state)}
              <WrappedComponent {...this.props} />
            </div>
          );
        }
      };
    }
    const WrappedButton = fadeOutWrapper(Button);
    
    ReactDOM.render(<App />, document.getElementById('root'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
    <div id="root"></div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 2017-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-27
      相关资源
      最近更新 更多