简体   繁体   English

Algolia - 关闭模态时存储 RefinementList 值

[英]Algolia - Store RefinementList value when close Modal

I'm building a filter Modal in algolia.我正在 algolia 中构建一个过滤器模态。 On that filter Modal, I have a standard refinementlist (see below code).在那个过滤器模态上,我有一个标准的细化列表(见下面的代码)。 When the user hits "Search" on the modal, the refinementlist values are lost (ie not applied to my component), but there is no guide on how to store refinementlist output.当用户点击模态上的“搜索”时,细化列表值将丢失(即未应用于我的组件),但没有关于如何存储细化列表 output 的指南。

What I'd like is to essentially have my Refinement list values not to clear when I close my modal.我想要的基本上是让我的优化列表值在我关闭模式时不被清除。

refinementlist.js细化列表.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;

filter.js过滤器.js

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

const Filters = () => {
    return (

                <div>
                    <toRefine />
                </div>

    );
};

export default Filters;

MainPage.js主页.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;

Each React InstantSearch widget is responsible for its UI state and needs to be mounted.每个 React InstantSearch 小部件负责其 UI state 并需要挂载。 I'm not familiar with react-modal , but from what I gather reading their documentation, the modal instance is destroyed when closing, not hidden, so the RefinementList is unmounted as well.我不熟悉react-modal ,但从我阅读他们的文档中收集到的信息,模态实例在关闭时被破坏,而不是隐藏,因此RefinementList也被卸载。

What you can do to circumvent this behavior is persist the widget's state manually whenever it changes except when closing the modal, and inject it to the widget as its default refinement.您可以采取的措施来规避此行为,只要它更改时手动保留小部件的 state,关闭模态时除外,并将其作为默认细化注入小部件。

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>
  );
}

You always need to have the RefinementList mounted in the application so that the state is persisted in React InstantSearch's internal state. You can do it declaratively by creating a virtual refinement list, which doesn't render anything, using the connectRefinementList connector.您始终需要在应用程序中安装RefinementList ,以便 state 保留在 React InstantSearch 的内部 state 中。您可以通过使用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>
  );
}

You can see it in action in this CodeSandbox demo .您可以在此CodeSandbox 演示中看到它的运行情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM