You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React.js提交搜索后更新Bing Web API搜索结果(SERP格式)求助

问题描述

使用Bing Web Search API时,在自定义搜索栏输入查询能获取数据,但提交后无法将数据展示在搜索结果中,需要访问返回数据里webPages下的value元素。

相关代码

useSearch.js

import { useState, useEffect } from 'react';
import axios from 'axios';

const BASE_URL = 'https://api.bing.microsoft.com/v7.0/search';
const API_KEY = '0760f20a58f340a4ba3ce10857c43142'

const useSearch = ( {searchTerm} ) => {
    const [data, setData] = useState('');


    useEffect(() => {
        const fetchData = async () => {
            if (!searchTerm) return;
            try {
                const response = await axios.get(`${BASE_URL}`, {
                    headers: {
                        'Ocp-Apim-Subscription-Key': API_KEY,
                    },
                    params: {
                        'q': `${searchTerm}`,
                        'count': 10,
                        'mkt': 'en-us',
                    },
                });
                setData(response.data.webPages.value);
                // shows data from search bar
                console.log(response.data);

            } catch (error) {
                console.error('Error fetching data:', error);
            }
        };
        fetchData();
    }, [searchTerm]);

    return data;

};

export default useSearch;

SearchResults.js

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import TileItems from './TileItems';
import useSearch from './UseSearch';

const SearchResults = () => {
    const [theme, setTheme] = useState('light');
    const { data } = useSearch({ searchTerm: searchData });

    return (
      <div className=''>
        <main className={`main-container ${theme}`}>
          <section className="eighty" id="item-tiles">
            <h1>Search Results</h1>
            {data ? (
                <ul>
                  {data.map((i) => (
                      <TileItems
                          key={i.id}
                          image={i.thumbnailUrl}
                          title={i.name}
                          description={i.snippet}
                          website={i.url}
                      />
                  ))}
                </ul>
                ) : (
                  <p>Loading...</p>
                )}
          </section>
          <section id="item-tiles-right" className="twenty">
            <h2 id='col-2-header'>News</h2>
               {video ? (
                  <ul>
                    {/* this section is still under development */}
                    {video.map((v) => (
                        <iframe
                          id='ytplayer'
                          src={v.contentUrl}
                          frameborder='0'
                          allow='autoplay; encrypted-media'
                          width='100%'
                          height='360'
                          title='video'
                        />
                     ))}
                  </ul>
                  ) : (
                    <p>Loading...</p>
                  )}
          </section>
        </main>
      </div>
  );
};
import React, { useState } from 'react';
import './NavBar.css';
import logo_light from '../../assets/spigot-logo.png';
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';
import useSearch from '../UseSearch';


function NavBar({theme, setTheme, setSearchTerm}) {
  const [searchQuery, setSearchQuery] = useState('');
  const { data } = useSearch({ searchTerm: searchQuery});
  // console.log(setSearchQuery);

  /* 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'>
        <form>
           <input  className='search-bar' type='text' placeholder='Search' onChange={(e) => 
            setSearchQuery(e.target.value)}></input>
        </form>
        <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
解决方案

核心问题梳理

  1. 搜索状态未全局同步:NavBar的searchQuery和SearchResults的searchData无关联,导致结果组件拿不到用户输入的关键词。
  2. Hook返回值使用错误:useSearch直接返回data,但组件里用了解构语法const { data } = useSearch(...),引发解构错误。
  3. 初始状态类型不匹配:useSearch中data初始值是空字符串,后续要存储数组,类型不匹配会导致map调用失败。
  4. 未定义变量直接使用:SearchResults里的searchData和video未声明,直接使用会触发报错。

分步修复

1. 全局管理搜索状态

在父组件(如App.js)中统一维护搜索关键词,通过props传递给子组件:

// App.js示例
import React, { useState } from 'react';
import NavBar from './components/Nav';
import SearchResults from './components/SearchResults';

function App() {
  const [theme, setTheme] = useState('light');
  const [searchTerm, setSearchTerm] = useState('');

  return (
    <div className={`App ${theme}`}>
      <NavBar theme={theme} setTheme={setTheme} setSearchTerm={setSearchTerm} />
      <SearchResults searchTerm={searchTerm} />
    </div>
  );
}

export default App;

2. 修复NavBar组件,同步搜索关键词

更新NavBar,在表单提交时将输入的查询同步到父组件,并移除不必要的useSearch调用:

// Nav.js修改部分
<form onSubmit={(e) => {
  e.preventDefault();
  setSearchTerm(searchQuery);
}}>
  <input className='search-bar' type='text' placeholder='Search' 
         onChange={(e) => setSearchQuery(e.target.value)}
         value={searchQuery} />
</form>

3. 调整useSearch Hook的初始状态与容错逻辑

// useSearch.js修改
const useSearch = ( {searchTerm} ) => {
    const [data, setData] = useState([]); // 初始值设为空数组,匹配后续数据类型

    useEffect(() => {
        const fetchData = async () => {
            if (!searchTerm) {
                setData([]);
                return;
            }
            try {
                const response = await axios.get(BASE_URL, {
                    headers: {
                        'Ocp-Apim-Subscription-Key': API_KEY,
                    },
                    params: {
                        q: searchTerm,
                        count: 10,
                        mkt: 'en-us',
                    },
                });
                // 增加容错,避免webPages不存在时抛出错误
                setData(response.data.webPages?.value || []);
            } catch (error) {
                console.error('Error fetching data:', error);
                setData([]);
            }
        };
        fetchData();
    }, [searchTerm]);

    return data; // 直接返回数组,无需包装成对象
};

4. 修复SearchResults组件的变量问题

// SearchResults.js修改
import React from 'react';
import TileItems from './TileItems';
import useSearch from './UseSearch';

const SearchResults = ({ searchTerm }) => {
    const data = useSearch({ searchTerm }); // 直接接收返回的数组

    return (
      <div className=''>
        <main className={`main-container`}>
          <section className="eighty" id="item-tiles">
            <h1>Search Results</h1>
            {data.length > 0 ? (
                <ul>
                  {data.map((item) => (
                      <TileItems
                          key={item.id}
                          image={item.thumbnailUrl}
                          title={item.name}
                          description={item.snippet}
                          website={item.url}
                      />
                  ))}
                </ul>
                ) : (
                  searchTerm ? <p>No results found</p> : <p>Enter a search term</p>
                )}
          </section>
          <section id="item-tiles-right" className="twenty">
            <h2 id='col-2-header'>News</h2>
            <p>Under development</p>
          </section>
        </main>
      </div>
  );
};

验证要点

  • 检查浏览器控制台是否有未定义变量、解构错误等提示。
  • 确认API请求成功后,response.data.webPages.value能正确获取到结果数组。
  • 验证搜索关键词在父组件、NavBar、SearchResults之间的传递是否顺畅。

内容的提问来源于stack exchange,提问作者jesse morris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 02:35:01