我正在尝试使用 bing web api 创建一个搜索栏,但无法弄清楚如何使用 axios 将 api 密钥和搜索查询一起传递到 get 请求中。另外,如何将用户输入从搜索栏获取到获取请求中。如果有人能帮忙提供详细的答案,我将非常感激!
https://learn.microsoft.com/en-us/bing/search-apis/bing-web-search/search-the-web
这是我尝试过的:
import React, { useEffect, useState } from 'react';
import axios from 'axios';
// Search bar capabilities under development
const BASE_URL = 'https://api.bing.microsoft.com/v7.0/search'
const API_KEY = process.env.REACT_APP_SEARCH_KEY;
const useSearch = (searchTerm) => {
const [data, setData] = useState(null);
const headers = {
headers: {
'Ocp-Apim-Subscription-Key:': 'API_KEY'
}
}
const params = {
headers: {
'q': `${searchTerm}`,
'count': 10,
'mkt': 'en-us',
}
}
useEffect(() => {
const fetchData = async () => {
const response = axios.get(`${BASE_URL}`, headers=headers);
setData(response?.data);
};
fetchData();
}, [searchTerm])
return {
data,
};
};
export default useSearch;
这就是我的导航文件的样子:
import React from 'react'
import './NavBar.css'
import logo_dark from '../../assets/logo_light2.png'
import search_icon_light from '../../assets/search-w.png'
import search_icon_dark from '../../assets/search-b.png'
import toggle_light from '../../assets/night.png'
import toggle_dark from '../../assets/day.png'
function NavBar({theme, setTheme}) {
/* ternary clause to change theme between light and dark mode */
const toggle_mode = () => {
theme == 'light' ? setTheme('dark') : setTheme('light');
}
return (
<div className='navbar' >
<img src={theme == 'light' ? logo_light : logo_dark} alt='' className='logo' />
<ul className='nav-list'>
<li>SEARCH</li>
</ul>
<div className='search-box'>
<input className='search-bar' type='text' placeholder='Search'></input>
<img className='search-icon' src={theme == 'light' ? search_icon_light : search_icon_dark} alt='' />
</div>
<img onClick={() => {toggle_mode()}} src={theme == 'light' ? toggle_light : toggle_dark} alt='' className='toggle-icon'></img>
</div>
)
}
export default NavBar
在您的
useSearch
钩子中,您需要执行此操作。我在注释代码中添加了解释我正在做什么以及我更改了什么
import React, { useEffect, useState } from "react";
import axios from "axios";
// Search bar capabilities under development
const BASE_URL = "https://api.bing.microsoft.com/v7.0/search";
const API_KEY = process.env.REACT_APP_SEARCH_KEY;
const apiAuthHeader = {
"Ocp-Apim-Subscription-Key:": API_KEY,
};
// added named hook params for better readability
const useSearch = ( {searchTerm} ) => {
const [data, setData] = useState(null);
// Just a suggestion for further improvements
// TODO: Debounce search
// TODO: Add loading state and error handling
useEffect(() => {
// Every time the search term changes
// it will create a new params object with a new
// search term
const searchParams = {
q: `${searchTerm}`,
count: 10,
mkt: "en-us",
};
const fetchData = async () => {
// supports options, so you can specify two options in your case,
// headers for auth and params for your search params
const response = axios.get(`${BASE_URL}`, {
headers: apiAuthHeader,
params: searchParams,
});
setData(response?.data);
};
// only call fetch data if the search term is not empty
if (searchTerm)
{
fetchData();
}
}, [searchTerm]);
return {
data,
};
};
我发现您没有在导航栏中的任何地方使用搜索挂钩。请记住,您还必须添加 debouching,以免每次击键时都会向 api 发送垃圾邮件。我建议在这里查看 debouching,因为 debouching 不在问题的范围内。 https://www.freecodecamp.org/news/debouncing-explained/
我做了一些小的修改,我假设
data
是一个数组,所以你必须将数据呈现给你认为合适的人。还要记住检查是否有数据,否则在初始获取时不会呈现任何内容。
import React, { useState } from "react";
import "./NavBar.css";
// import your hook
function NavBar({ theme, setTheme }) {
const [searchQuery, setSearchQuery] = useState("");
// search query state is passed down to the hook
const { data } = useSearch({ searchTerm: searchQuery });
/* ternary clause to change theme between light and dark mode */
const toggle_mode = () => {
theme == "light" ? setTheme("dark") : setTheme("light");
};
return (
<div className="navbar">
<img
src={theme == "light" ? logo_light : logo_dark}
alt=""
className="logo"
/>
<ul className="nav-list">
<li>SEARCH</li>
</ul>
<div className="search-box">
<input
onChange={(e) => setSearchQuery(e.target.value)}
className="search-bar"
type="text"
placeholder="Search"
/>
<img
className="search-icon"
src={theme == "light" ? search_icon_light : search_icon_dark}
alt=""
/>
</div>
<img
onClick={() => {
toggle_mode();
}}
src={theme == "light" ? toggle_light : toggle_dark}
alt=""
className="toggle-icon"
></img>
{data && <p>{data}</p>}
</div>
);
}
export default NavBar;