在配置文件中通知功能已安装组件

时间:2019-11-26 12:20:21

标签: reactjs

我有一个使用Shepherd作为演练库的应用程序。在我的Root组件中,导入Shepherd component。我将步骤的配置和游览选项作为道具传递。这些配置变量放置在单独的文件中。

Root.js:

import React, { Component } from "react";
import { BrowserRouter as Router } from "react-router-dom";    
import App from "./App";
import { ShepherdTour } from 'react-shepherd';
import { tourOptions, steps } from '../utils/shepherd-config';

class Root extends Component {
  render() {
    return (
      <Router>
        <ShepherdTour steps={steps} tourOptions={tourOptions}>
          <App />
        </ShepherdTour>
      </Router>
    );
  }
}

export default Root;

步骤配置示例:

export const steps = [
    {
        attachTo: { element: '.exampleTemplates', on: 'left' },
        advanceOn: { selector: '.exampleTemplates', event: 'click' },
        beforeShowPromise: function () {
            return new Promise(function (resolve) {
                setTimeout(function () {
                    resolve();
                }, 2500);
            })
        },
        buttons: buttonsForActions,
        title: "Example meeting templates",
        text: ["Here are some example meeting templates. Click on one of them to add them to your current meeting templates so you can edit them later."],
    },
];

在Shepherd中,这些步骤中有一个函数beforeShowPromise,它会在将步骤模态附加到元素上之前等待。如您所见,我目前已承诺在2.5秒后解决。我这样做是因为该步骤所附加的组件需要花费一些时间才能加载。但这是您不想要的,因为互联网速度可能很慢。因此,我想检查组件是否确实挂载,并在配置中通知该函数是否挂载。

enter image description here

我创建了某种图表以使其更加清晰。该应用程序由许多不同的组件组成,因此我认为将其作为状态从子级传递到父级有点麻烦。有没有一种好的干净的解决方案,可以让config文件中的功能知道该组件已安装?

1 个答案:

答案 0 :(得分:0)

我最终得到了一个“非反应”解决方案,因为我的配置文件对生命周期方法一无所知。我创建了一个函数来检查元素是否存在,如果不存在,则应在500毫秒后再次检查:

function waitForElementToDisplay(selector) {
    return new Promise(function (resolve) {
        (function checkIfElementExists() {
            if (document.querySelector(selector) !== null) {
                resolve();
            } else {
                setTimeout(checkIfElementExists, 500);
            }
        })();
    })
}

然后在beforeShowPromise函数中使Promise函数异步,以便它可以等待,直到waitForElementToDisplay承诺被解决。

  beforeShowPromise: function () {
        return new Promise(async function (resolve) {

            const selector = '.exampleTemplates';

            await waitForElementToDisplay(selector).then(() => {
                resolve();
            });
        })
    },