我没有几个组件,即about
、home
、contact
、header
、footer
、search
。我使用react-router-dom
在所有页面之间进行路由。在App.js
中,我根据路由加载所有组件,但是,对于footer
和header
,我不需要路由,它们被加载到所有页面中。Header
由导航和search
组件组成。search
组件是用户输入文本以搜索内容的地方。现在,这个带有header
组件的search
组件将在所有页面中呈现,因为我在App.js
文件中使用它。现在我想要的是当用户在搜索某物时,我希望用搜索内容替换当前页面的内容。我该怎么做?
这是我的App.js
import { BrowserRouter, Route, Switch } from "react-router-dom";
import About from "./about";
import Contact from "./contact";
import Home from "./home";
import Header from "./header";
import Footer from "./footer";
export default function App() {
return (
<BrowserRouter>
<Header />
<div>
<Switch>
<Route path="/" exact={true}>
<Home />
</Route>
<Route path="/home" exact={true}>
<Home />
</Route>
<Route path="/about">
<About />
</Route>
<Route path="/contact">
<Contact />
</Route>
</Switch>
</div>
<Footer />
</BrowserRouter>
);
}
这是我的头像
import { Link } from "react-router-dom";
import Search from "./search";
const Header = () => {
return (
<>
<ul>
<li>
<Link to="home">Home</Link>
</li>
<li>
<Link to="about">About</Link>
</li>
<li>
<Link to="contact">Contact</Link>
</li>
</ul>
<Search />
</>
);
};
export default Header;
这是我的搜索组件
import { useState } from "react";
const Search = () => {
const apiKey = "test key";
const baseUrl = "https://content.guardianapis.com/";
const [items, setItems] = useState();
const searchNews = async (event) => {
const query = event.target.value;
if (query === "") {
const news = await fetchNews("news", 15, 1);
console.log();
setItems(news.response.results);
return;
}
console.log(query);
const news = await fetchNews(query, 15, 1);
setItems(news.response.results);
};
const fetchNews = async (section, pageSize, page) => {
const url = `${baseUrl}${section}?page-size=${pageSize}&page=${page}&api-key=${apiKey}`;
const news = await fetch(url);
return await news.json();
};
return (
<>
<input
type="text"
name="search"
placeholder="Enter search term"
onChange={searchNews}
/>
</>
);
};
export default Search;
下面是到代码框https://codesandbox.io/s/muddy-forest-4vbgs?file=/src/search.js:0-970的链接
您可以在上面的链接中找到其余的组件。请帮助我如何实现这个场景?
发布于 2021-07-10 09:22:39
我会将Search
组件中的搜索获取逻辑抽象为应用程序的其他组件可以使用的React上下文。
SearchContext.js
import { createContext, useEffect, useContext, useState } from "react";
export const SearchContext = createContext({
search: "",
searchResult: [],
setSearch: () => {}
});
export const useSearch = () => useContext(SearchContext);
const SearchProvider = ({ children }) => {
const apiKey = "test key";
const baseUrl = "https://content.guardianapis.com/";
const [search, setSearch] = useState('');
const [items, setItems] = useState([]);
useEffect(() => {
const searchNews = async () => {
if (search.length < 3) {
const news = await fetchNews("news", 15, 1);
console.log();
setItems(news.response.results);
return;
}
console.log(search);
const news = await fetchNews(search, 15, 1);
setItems(news.response.results);
};
const fetchNews = async (section, pageSize, page) => {
const url = `${baseUrl}${section}?page-size=${pageSize}&page=${page}&api-key=${apiKey}`;
const news = await fetch(url);
return await news.json();
};
searchNews();
}, [search]);
return (
<SearchContext.Provider
value={{
search,
searchResult: items,
setSearch: (e) => setSearch(e.target.value)
}}
>
{children}
</SearchContext.Provider>
);
};
export default SearchProvider;
在index.js中提供上下文
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import SearchProvider from "./SearchContext";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<SearchProvider>
<App />
</SearchProvider>
</StrictMode>,
rootElement
);
search.js -设置搜索值
import { useSearch } from "./SearchContext";
const Search = () => {
const { setSearch } = useSearch();
return (
<>
<input
type="text"
name="search"
placeholder="Enter search term"
onChange={setSearch}
/>
</>
);
};
在任何路由中,组件显示搜索值和/或结果。
home.js
import { useSearch } from './SearchContext';
const Home = () => {
const { search } = useSearch();
return (
<>
<h3>Home page</h3>
<div>Search value: {search}</div>
</>
);
};
演示
更新
如果您想要添加一个加载指示符,那么它很可能与您以前所做的一样。
complete.
isLoading
状态。从上下文中提取isLoading
true和isLoading
false --从上下文获取isLoading
状态。H 218G 219
SearchProvider:
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const searchNews = async () => {
console.log(search);
setIsLoading(true); // <-- start loading
const news = await fetchNews(search.length ? search : "news", 15, 1);
setItems(news);
setIsLoading(false); // <-- clear loading
};
const fetchNews = async (section, pageSize, page) => {
const url = `${baseUrl}${section}?page-size=${pageSize}&page=${page}&api-key=${apiKey}`;
const news = await fetch(url);
return await news.json();
};
searchNews();
}, [search]);
UI示例:
const Home = () => {
const { isLoading, search, searchResult } = useSearch();
return (
<>
<h3>Home page</h3>
{isLoading ? (
<h1>LOADING...</h1>
) : (
<div>
<div>Search value: {search}</div>
{searchResult..map( ..... )}
</div>
)}
</>
);
};
https://stackoverflow.com/questions/68326273
复制相似问题