用搜索内容替换搜索当前页面内容

x759pob2  于 2021-09-23  发布在  Java
关注(0)|答案(1)|浏览(328)

我有几个组件,即。 about , home , contact , header , footer , search . 我正在使用 react-router-dom 用于在所有页面之间进行路由。在里面 App.js 我正在加载基于路由的所有组件,但是,对于 footerheader 我不需要路线,他们在所有页面加载。 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;

这里是到codesandbox的链接https://codesandbox.io/s/muddy-forest-4vbgs?file=/src/search.js:0-970
您可以在上面的链接中找到其余的组件。请帮助我如何实现此场景?

mrwjdhj3

mrwjdhj31#

我将从 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>
    </>
  );
};

演示

更新

如果您想添加一个加载指示器,那么它可能与您之前所做的相同。
添加 isLoading 根据上下文陈述。
设置 isLoading 获取和删除时为true
设置 isLoading 获取完成时为false。
消耗 isLoading 从上下文中陈述。
搜索提供商:

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]);

用户界面示例:

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>
      )}
    </>
  );
};

相关问题