1

我正在 algolia 中构建过滤器 Modal。在那个过滤器模式上,我有一个标准的细化列表(见下面的代码)。当用户在模式上点击“搜索”时,refinementlist 值会丢失(即未应用于我的组件),但没有关于如何存储细化列表输出的指南。

我想要的是在我关闭我的模式时基本上让我的 Refinement 列表值不被清除。

细化列表.js

import React from 'react';

import { RefinementList } from 'react-instantsearch-dom';

const toRefine = () => {
    return (
        <div>
                <RefinementList 
                    attribute={`tags`} 
                    searchable 
                    limit={5} 
                />
        </div>
    );
};

export default toRefine;

过滤器.js

import React from 'react';
import toRefine from './toRefine';

const Filters = () => {
    return (

                <div>
                    <toRefine />
                </div>

    );
};

export default Filters;

MainPage.js

import React, { useState } from 'react';
import Hits from './hits';
import algoliasearch from 'algoliasearch/lite';
import { InstantSearch } from 'react-instantsearch-dom';
import Modal from 'react-modal';
import Filters from './filters';

Modal.setAppElement('#root');   
const searchC = algoliasearch($ENV_VARS);

const Page = () => {
    const [ modalIsOpen, setIsOpen ] = useState(false); //Hook for modal

    function openModal() {
        setIsOpen(true);
    }
    function closeModal() {
        setIsOpen(false);
    }

    return (
        <div>
            <InstantSearch
                indexName="index" 
                searchClient={searchC}
            >
                <CustomSearchBox />
                <button onClick={openModal}>Show FILTERS</button>
                <Configure hitsPerPage={20} />
                <Hits />
                <Modal
                    isOpen={modalIsOpen}
                    onRequestClose={closeModal}
                    contentLabel="filterElement"
                    className={styles.modal}
                    overlayClassName={styles.overlay}
                >
                    <FilterPage />
                </Modal>
            </InstantSearch>
        </div>
    );
};

export default Page;
4

1 回答 1

0

每个 React InstantSearch 小部件都负责其 UI 状态并且需要被挂载。我不熟悉react-modal,但是从我阅读他们的文档中收集到的信息,模态实例在关闭时被破坏,而不是隐藏,因此RefinementList也被卸载。

规避此行为的方法是在小部件状态发生变化时手动保持小部件的状态(关闭模式时除外),并将其作为默认细化注入小部件。

function App() {
  const [brandState, setBrandState] = React.useState([]);

  // ...

  return (
    <InstantSearch
      onSearchStateChange={(state) => {
        if (modalIsOpen && state.refinementList?.brand) {
          setBrandState(state.refinementList.brand);
        }
      }}
    >
      <Modal isOpen={modalIsOpen}>
        <RefinementList
          defaultRefinement={brandState}
          attribute="brand"
        />
      </Modal>
    </InstantSearch>
  );
}

您始终需要RefinementList在应用程序中安装该状态,以便状态保持在 React InstantSearch 的内部状态中。您可以通过使用连接器创建一个不呈现任何内容的虚拟细化列表来声明式地执行此操作connectRefinementList

import { connectRefinementList } from 'react-instantsearch-dom';

// ...

const VirtualRefinementList = connectRefinementList(() => null);

function App() {
  // ...

  return (
    <InstantSearch
      onSearchStateChange={(state) => {
        if (modalIsOpen && state.refinementList?.brand) {
          setBrandState(state.refinementList.brand);
        }
      }}
    >
      <VirtualRefinementList defaultRefinement={brandState} attribute="brand" />
      {/* ... */}
    </InstantSearch>
  );
}

您可以在此CodeSandbox 演示中看到它的实际效果。

于 2020-11-28T14:50:59.477 回答