Я не уверен на 100%, что понимаю ваше намерение, но, возможно, это может сработать ... где это позволяет вам добавлять / удалять запросы вручную через взаимодействие с пользователем и / или путем навигации по истории браузера (мышь назад и вперед) , Также будут сохраняться запросы при обновлении страницы.
Если вам абсолютно необходимо использовать опцию params
, я бы поместил ее в path
Маршрута и получил к ней доступ через (this.props.)location.params
. Если его необходимо динамически заменить, лучше переместить его в параметры запроса, например: /movies/action?subcategory=comedy&year=2019&starring=Bob%20Saget
. Когда вы начинаете менять параметры, структура вашего маршрута может оказаться излишне загроможденной и трудной для управления.
Примечания. В этом примере qs используется для анализа (this.props.)location.search
простой строки и объекта. запросов. Кроме того, он также использует рендерный реквизит (см., Например, pages/Homes/index.js
) для передачи родительского state
ребенку как props
через function
.
* 1020. * Демо :
https://c7isk.csb.app/
Источник :
компоненты / QueryHandler
import { PureComponent } from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router-dom";
import { setQuery, stringifyQuery } from "../../utils";
class QueryHandler extends PureComponent {
state = setQuery(this.props.location.search);
static getDerivedStateFromProps = ({ location }) => setQuery(location.search);
pushToLocation = query =>
this.props.history.push(`${this.props.location.pathname}?${query}`);
updateQuery = nextQuery =>
this.pushToLocation(
stringifyQuery({
...this.state.queries,
...nextQuery
})
);
clearFilters = () => this.props.history.push(this.props.location.pathname);
render = () =>
this.props.children({
...this.state,
clearFilters: this.clearFilters,
updateQuery: this.updateQuery
});
}
QueryHandler.propTypes = {
children: PropTypes.func.isRequired,
history: PropTypes.shape({
push: PropTypes.func.isRequired
}),
location: PropTypes.shape({
pathname: PropTypes.string,
search: PropTypes.string
})
};
export default withRouter(QueryHandler);
компоненты / фильтры
import React, { PureComponent } from "react";
import PropTypes from "prop-types";
class Filters extends PureComponent {
handleChange = ({ target: { name, value } }) => {
this.props.updateQuery({ [name]: value });
};
clearQuery = name => {
this.props.updateQuery({ [name]: null });
};
render = () => {
const currentQuery = {
eventdate: "",
eventtype: "",
teamid: "",
...this.props.queries
};
return (
<div style={{ margin: "0 auto", width: 500 }}>
<div className="filter-container">
<label className="label" htmlFor="eventdate">
Event Date:
</label>
<input
className="uk-input"
name="eventdate"
type="date"
value={currentQuery.eventdate}
onChange={this.handleChange}
/>
{currentQuery.eventdate && (
<button
className="uk-button uk-button-danger"
type="button"
onClick={() => this.clearQuery("eventdate")}
>
X
</button>
)}
</div>
<div className="filter-container">
<label className="label" htmlFor="eventtype">
Event Type:
</label>
<select
name="eventtype"
value={currentQuery.eventtype}
className="uk-select"
onChange={this.handleChange}
>
<option value="" disabled hidden>
Select your option
</option>
<option value="game">Game</option>
<option value="practice">Practice</option>
<option value="promo">Promo</option>
</select>
{currentQuery.eventtype && (
<button
className="uk-button uk-button-danger"
type="button"
onClick={() => this.clearQuery("eventtype")}
>
X
</button>
)}
</div>
<div className="filter-container">
<label className="label" htmlFor="teamid">
Team ID:
</label>
<input
className="uk-input"
name="teamid"
type="number"
min="0"
value={currentQuery.teamid}
placeholder="Select a team ID..."
onChange={this.handleChange}
/>
{currentQuery.teamid && (
<button
className="uk-button uk-button-danger"
type="button"
onClick={() => this.clearQuery("teamid")}
>
X
</button>
)}
</div>
<div style={{ textAlign: "center" }}>
<button
className="uk-button uk-button-primary"
type="button"
onClick={this.props.clearFilters}
>
Clear All Filters
</button>
</div>
</div>
);
};
}
Filters.propTypes = {
queries: PropTypes.shape({
eventdate: PropTypes.string,
eventtype: PropTypes.string,
teamid: PropTypes.string
}),
updateQuery: PropTypes.func.isRequired
};
export default Filters;
утилит / index. js
import qs from "qs";
/**
* Stringifies an object of query properties.
*
* @function stringifyQuery
* @param {object} query
* @returns {string}
*/
export const stringifyQuery = query => qs.stringify(query, { skipNulls: true });
/**
* Parses a stringified query to an object of queries.
*
* @function parseQuery
@param {string} query
* @returns {object} - An object of query properties.
*/
export const parseQuery = query =>
qs.parse(query, {
ignoreQueryPrefix: true
});
/**
* Utilizes the functions above to parse and stringify a query.
*
* @function setQuery
* @param {string} query
* @returns {object}
*/
export const setQuery = query => {
const queries = parseQuery(query);
const queryString = stringifyQuery(queries);
return { queries, queryString };
};
страниц / Home
import React from "react";
import QueryHandler from "../../components/QueryHandler";
import Filters from "../../components/Filters";
function Home() {
return (
<div className="home">
<QueryHandler>
{props => (
<>
<Filters {...props} />
<pre style={{ background: "#ebebeb" }}>
<code>{JSON.stringify(props, null, 4)}
)} ); } экспорт по умолчанию Home;