#reactjs #react-router #react-context
Вопрос:
Вот 3 основных компонента searchBar
, которые относятся к форме строки поиска и searchPage
компоненту, который отображает результаты поиска, и, конечно же, app
компоненту, который содержит их все.
механизм:
- пользователь отправляет ввод в компоненте панели поиска,
handleSubmit
запускается функция, которая изменяет состояниеsetSearchedProducts
на входное значениеuseContext
И перемещается на («/Страница поиска»)history.push()
.
import {useState, useContext } from "react";
import { useHistory } from "react-router-dom";
import { LocaleContext } from "../../../LocaleContext";
const SearchBar = () => {
const history = useHistory();
const {setSearchedTerm} = useContext(LocaleContext);
const handleSubmit = (SearchTerm) => {
setSearchedProducts(SearchTerm)
history.push("/SearchPage");
}
return (
<form>
<input onSubmit={(e) => handleSubmit(e.target.value)}>
</input>
<button type="submit">Submit</button>
</form>
)
}
export default SearchBar
- значение отправляется компоненту приложения контекстом реакции, и
состояние устанавливается равным значению, продолжая
при этом переходить на страницу («/SearchPage»).
import { useState, useMemo } from "react";
import { searchBar, searchPage } from "./components";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import {LocaleContext} from "./LocaleContext"
const App = () => {
const [searchedTerm, setSearchedTerm] = useState("");
const providerValue = useMemo(() => ({searchedTerm, setSearchedTerm}),
[searchedTerm, setSearchedTerm])
return (
<Router>
<LocaleContext.Provider value={providerValue}>
<searchBar />
<Switch>
<Route exact path="/SearchPage">
<SearchPage />
</Route>
</Switch>
</LocaleContext.Provider>
</Router>
);
}
export default (App);
- отображение компонента SearchPage, который получает значение состояния
с помощьюuseContext
и сuseEffect
помощьюfetchProducts()
запускается функция, которая извлекает набор продуктов на основе значения
состояния.
import {useState, useEffect, useContext} from 'react';
import { LocaleContext } from "../../LocaleContext";
const SearchPage = ({}) => {
const [products, setProducts] = useState([]);
const {searchedTerm} = useContext(LocaleContext);
const fetchProducts = (term) => {
setLoading(true);
const url = new URL(
"https://example/products"
);
let params = {
"query": term
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
let headers = {
"Accept": "application/json",
"Content-Type": "application/json",
};
fetch(url, {
method: "GET",
headers: headers,
})
.then(response => response.json())
.then(json => {
setProducts(json);
});
}
useEffect(() => {
fetchProducts(searchedProducts)
}, [])
return (
{
products.map(product => (
<div>
{product.name}
</div>
))
}
)
}
export default SearchPage
Проблемы:
- когда маршрутизатор изменяет значение состояния компонента («/Страница поиска»), оно теряется, то есть возвращается к значению«».?
- меньшая проблема, если пользователь отправляет пустую строку (» «), а API требуется значение или оно выдаст ошибку, каково решение этой проблемы?
- есть ли способ сохранить значение после перезагрузки страницы?
import {createContext} from "react";
export const LocaleContext = createContext(null);
это localeContext
компонент, если он необходим.
Ответ №1:
вы должны добавить e.preventDefault()
свой onSubmit
обработчик. В противном случае вы получаете перезагрузку страницы, которая приводит к потере состояния.
Комментарии:
1. это сработало, но есть ли способ сохранить значение после перезагрузки страницы?
2. да, вы можете хранить данные локально на клиенте (с помощью локального хранилища / файлов cookie и т.д.) Или на сервере.