Reactour - 如何禁用下一步直到正确的用户操作?

问题描述

我正在使用 Reactour 库在 React 中构建用户导览(duh),这对于简单的步骤来说已经足够简单了,但我不知道如何阻止用户走得更远直到他们完成与当前步骤相关的操作。

例如,在第 1 步中,我希望他们在继续之前执行搜索(输入文本并提交)。现在我正在使用 goTo() 函数自动前进到下一步,但是如何防止他们只使用导航箭头而不完全禁用导航(以防他们需要返回)?

export const steps: ReactourStep[] = [
  // This will automatically advance to the next step after a search... but the user Could also just use the tour navigation instead...
  {
    selector: '.search-input',content: ({ goTo }: { goTo: (step: number) => void }) => {
      const searchBar = document.getElementById('search-bar') as HTMLInputElement;
      const searchButton = document.querySelector('.search-button') as HTMLButtonElement;

      // Timeout in order to allow for results to render
      searchButton.addEventListener('click',() => setTimeout(() => {
        if (searchBar.value !== '' && document.querySelector('.no-results') === null) {
          goTo(1);
        }
      },1000));

      return (
        <div>
          You can search using keywords and boolean expressions.
        </div>
      );
    }
  },{
     // Step 2 here
  }
]

我也尝试将条件 disabled 布尔值与自定义按钮一起使用,但与 React 不同的是,它不会立即重新渲染——仅当用户重新访问该步骤时——这违背了整个目的。

如果有帮助,库 GitHub 有与我类似的问题,但没有回应(herehere)。

解决方法

我通过使用一种方法来构建 <Tour/> 组件的步骤,并传入一个状态设置器来控制是否显示导航/启用键盘交互:

function createSteps (setLockTour) {
  return [
    // Step which requires a specific action...
    {
      content: () => {
        return ( /* Your content */ )
      },action: node => {
        setLockTour(true)

        // Or whatever event you're waiting for
        node.onclick = () => {
          setLockTour(false)
          // ...
        }
      }
    }
  ]
}

然后对于您的游览组件:

const [lockTour,setLockTour] = useState(false)
//...
<Tour
  steps={createSteps(setLockTour)}
  disableKeyboardNavigation={lockTour}
  disableDotsNavigation={lockTour}
  showButtons={!lockTour}
/>