From af2141417ac504e47892821d01fb0f33a3f0b273 Mon Sep 17 00:00:00 2001 From: derek Date: Sun, 12 Jul 2020 22:58:48 -0400 Subject: [PATCH] ui.components.search: fix duplicate requests Deprecate componentWillReceiveProps for getDerivedStateFromProps --- ui/src/components/search.tsx | 96 +++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/ui/src/components/search.tsx b/ui/src/components/search.tsx index b2e554979..70a9faa2e 100644 --- a/ui/src/components/search.tsx +++ b/ui/src/components/search.tsx @@ -44,15 +44,17 @@ interface SearchState { searchResponse: SearchResponse; loading: boolean; site: Site; + searchText: string; } export class Search extends Component { private subscription: Subscription; private emptyState: SearchState = { - q: this.getSearchQueryFromProps(this.props), - type_: this.getSearchTypeFromProps(this.props), - sort: this.getSortTypeFromProps(this.props), - page: this.getPageFromProps(this.props), + q: Search.getSearchQueryFromProps(this.props), + type_: Search.getSearchTypeFromProps(this.props), + sort: Search.getSortTypeFromProps(this.props), + page: Search.getPageFromProps(this.props), + searchText: Search.getSearchQueryFromProps(this.props), searchResponse: { type_: null, posts: [], @@ -77,23 +79,23 @@ export class Search extends Component { }, }; - getSearchQueryFromProps(props: any): string { + static getSearchQueryFromProps(props: any): string { return props.match.params.q ? props.match.params.q : ''; } - getSearchTypeFromProps(props: any): SearchType { + static getSearchTypeFromProps(props: any): SearchType { return props.match.params.type ? routeSearchTypeToEnum(props.match.params.type) : SearchType.All; } - getSortTypeFromProps(props: any): SortType { + static getSortTypeFromProps(props: any): SortType { return props.match.params.sort ? routeSortTypeToEnum(props.match.params.sort) : SortType.TopAll; } - getPageFromProps(props: any): number { + static getPageFromProps(props: any): number { return props.match.params.page ? Number(props.match.params.page) : 1; } @@ -122,17 +124,23 @@ export class Search extends Component { this.subscription.unsubscribe(); } - // Necessary for back button for some reason - componentWillReceiveProps(nextProps: any) { + static getDerivedStateFromProps(props) { + return { + q: Search.getSearchQueryFromProps(props), + type_: Search.getSearchTypeFromProps(props), + sort: Search.getSortTypeFromProps(props), + page: Search.getPageFromProps(props), + }; + } + + componentDidUpdate(_, lastState) { if ( - nextProps.history.action == 'POP' || - nextProps.history.action == 'PUSH' + lastState.q !== this.state.q || + lastState.type_ !== this.state.type_ || + lastState.sort !== this.state.sort || + lastState.page !== this.state.page ) { - this.state.q = this.getSearchQueryFromProps(nextProps); - this.state.type_ = this.getSearchTypeFromProps(nextProps); - this.state.sort = this.getSortTypeFromProps(nextProps); - this.state.page = this.getPageFromProps(nextProps); - this.setState(this.state); + this.setState({ loading: true, searchText: this.state.q }); this.search(); } } @@ -163,7 +171,7 @@ export class Search extends Component { { } nextPage(i: Search) { - i.state.page++; - i.setState(i.state); - i.updateUrl(); - i.search(); + i.updateUrl({ page: i.state.page + 1 }); } prevPage(i: Search) { - i.state.page--; - i.setState(i.state); - i.updateUrl(); - i.search(); + i.updateUrl({ page: i.state.page - 1 }); } search() { @@ -441,37 +443,43 @@ export class Search extends Component { } handleSortChange(val: SortType) { - this.state.sort = val; - this.state.page = 1; - this.setState(this.state); - this.updateUrl(); + this.updateUrl({ sort: val, page: 1 }); } handleTypeChange(i: Search, event: any) { - i.state.type_ = Number(event.target.value); - i.state.page = 1; - i.setState(i.state); - i.updateUrl(); + i.updateUrl({ type_: Number(event.target.value), page: 1 }); } handleSearchSubmit(i: Search, event: any) { event.preventDefault(); - i.state.loading = true; - i.search(); - i.setState(i.state); - i.updateUrl(); + i.updateUrl({ + q: i.state.searchText, + type_: i.state.type_, + sort: i.state.sort, + page: i.state.page, + }); } handleQChange(i: Search, event: any) { - i.state.q = event.target.value; - i.setState(i.state); + i.setState({ searchText: event.target.value }); } - updateUrl() { - let typeStr = SearchType[this.state.type_].toLowerCase(); - let sortStr = SortType[this.state.sort].toLowerCase(); + updateUrl(paramUpdates: { + q?: string; + type_?: number; + sort?: SortType; + page?: number; + }) { + const qStr = paramUpdates.q || Search.getSearchQueryFromProps(this.props); + const typeStr = + SearchType[paramUpdates.type_] || + SearchType[Search.getSearchTypeFromProps(this.props)]; + const sortStr = + SortType[paramUpdates.sort] || + SortType[Search.getSortTypeFromProps(this.props)]; + const page = paramUpdates.page || Search.getPageFromProps(this.props); this.props.history.push( - `/search/q/${this.state.q}/type/${typeStr}/sort/${sortStr}/page/${this.state.page}` + `/search/q/${qStr}/type/${typeStr.toLowerCase()}/sort/${sortStr.toLowerCase()}/page/${page}` ); }