簡體   English   中英

如何使用ReactJs設計像電子商務網站那樣的通用過濾器?

[英]How to design a generic filter like ecommerce website have using ReactJs?

我打算建立一個像Gbif Have這樣的通用過濾器。 我的問題是如何解決這個問題。 我喜歡在這個項目中使用ReactJs。 為了設計這樣的通用過濾器,我需要與React和redux一起研究什么其他技術。

我嘗試僅使用React和redux設計此過濾器。

在我的方法中,我嘗試將查詢參數維護在get_data方法的狀態變量中,在該狀態變量中,我正在從服務器中獲取數據。 當有人單擊任何過濾器按鈕時,然后我將從該過濾器組件傳遞自定義事件以及查詢參數,並在get_data方法中處理此事件。 我再次在get_data方法中將此值保存在get_data狀態參數中,並再次獲取新的過濾數據。

現在,上述方法的問題在於,隨着參數數量的增加,它變得很難維護。

我的get_data構造函數如下所示。

 constructor(props){
      super(props);
      this.state={
        params:{
          max:10,
          offset:0,
          taxon:[],
          sGroup:[],
          classification:undefined,
          userGroupList:[],
          isFlagged:undefined,
          speciesName:undefined,
          isMediaFilter:undefined,
          sort:"lastRevised",
          webaddress:""

        },
        title:[],
        groupName:[],
        userGroupName:[],
        view:1
      }


      this.props.fetchObservations(this.state.params)
      this.loadMore=this.loadMore.bind(this);
    };

我從過濾器組件獲取數據的方式是這樣的。

這是我的handleInput方法,它從其中一個過濾器觸發onSelect方法。

handleInput(value,groupName){
    this.setState({
      active:true
    })
    this.props.ClearObservationPage();
    var event = new CustomEvent("sGroup-filter",{ "detail":{
        sGroup:value,
        groupName:groupName
    }
  });
  document.dispatchEvent(event);
  };

我在get_data組件中處理此事件的方式看起來像這樣。

sGroupFilterEventListner(e){
        const params=this.state.params;
        if(!params.sGroup){
          params.sGroup=[];
        }
        console.log("params.sGroup",params.taxon)
        params.sGroup.push(e.detail.sGroup)
        params.sGroup=_.uniqBy(params.sGroup)
        const groupName=this.state.groupName;
        var titleobject={};
        titleobject.sGroup=e.detail.sGroup;
        titleobject.groupName=e.detail.groupName;
        groupName.push(titleobject);
        let newgroupname=_.uniqBy(groupName,"sGroup")

        params.classification=params.classification;
        let isFlagged=params.isFlagged;
        let speciesName=params.speciesName;
        let MediaFilter=params.isMediaFilter;

        let taxonparams=params.taxon;
        taxonparams= taxonparams.join(",");
        let sGroupParams=params.sGroup;
            sGroupParams=sGroupParams.join(",");
        let userGroupParams=params.userGroupList;
         userGroupParams=userGroupParams.join(",");

        let newparams={
                  max:10,
                  sGroup:sGroupParams,
                  classification:params.classification,
                  offset:0,
                  taxon:taxonparams,
                  userGroupList:userGroupParams,
                  isFlagged:isFlagged,
                  speciesName:speciesName,
                  isMediaFilter:MediaFilter,
                  sort:params.sort

                }

        this.props.fetchObservations(newparams);
        this.setState({
                params:{
                  max:10,
                  sGroup:params.sGroup,
                  classification:params.classification,
                  offset:0,
                  taxon:params.taxon,
                  userGroupList:params.userGroupList,
                  isFlagged:isFlagged,
                  speciesName:speciesName,
                  isMediaFilter:MediaFilter,
                  sort:params.sort

                },
              groupName:newgroupname
        })
      }

我在我的componentDidMount和componentunmount方法中注冊和注銷了sGroupFilterEventListner。

目前,我也沒有考慮如果有人在網址欄中鍵入內容,過濾器面板會自動更改的情況。

請考慮以上所有情況,並向我建議一種通用的方法。 謝謝。

我當前的過濾器面板看起來像這樣 在此處輸入圖片說明

這是一個簡單的示例(僅響應,沒有Redux),我整理了動態數量的過濾器(在filters數組中定義,但是自然可以從任何地方獲取它)。

 const filters = [ { id: "name", title: "Name", type: "string" }, { id: "color", title: "Color", type: "choice", choices: ["blue", "orange"], }, { id: "height", title: "Height", type: "choice", choices: ["tiny", "small", "big", "huge"], }, { id: "width", title: "Width", type: "choice", choices: ["tiny", "small", "big", "huge"], }, ]; const filterComponents = { string: ({ filter, onChange, value }) => ( <input value={value || ""} onInput={e => onChange(filter.id, e.target.value)} /> ), choice: ({ filter, onChange, value }) => ( <select value={value || ""} onInput={e => onChange(filter.id, e.target.value)} size={1 + filter.choices.length} > <option value="">(none)</option> {filter.choices.map(c => ( <option value={c} key={c}> {c} </option> ))} </select> ), }; class App extends React.Component { constructor(props) { super(props); this.state = { filters: {} }; this.onChangeFilter = this.onChangeFilter.bind(this); } onChangeFilter(filterId, value) { const newFilterState = Object.assign({}, this.state.filters, { [filterId]: value || undefined, }); this.setState({ filters: newFilterState }); } renderFilter(f) { const Component = filterComponents[f.type]; return ( <div key={f.id}> <b>{f.title}</b> <Component filter={f} value={this.state.filters[f.id]} onChange={this.onChangeFilter} /> </div> ); } render() { return ( <table> <tbody> <tr> <td>{filters.map(f => this.renderFilter(f))}</td> <td>Filters: {JSON.stringify(this.state.filters)}</td> </tr> </tbody> </table> ); } } ReactDOM.render(<App />, document.querySelector("main")); 
 body { font: 12pt sans-serif; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <main/> 

(最初在https://codepen.io/akx/pen/JyemQQ?editors=0010上

希望這對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM