[英]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.