Next.js中如何实现点击按钮时触发数据请求?
解决方案
方案选型说明
你这个是典型的用户交互触发的客户端请求场景,直接用SWR即可,不需要使用getServerSideProps:getServerSideProps是Next.js的服务端预取能力,会在页面返回给用户之前就在服务端完成数据请求,完全不符合点击按钮才发起请求的需求。
核心实现思路
SWR默认只要传入的请求key为有效值,就会在组件挂载时自动发起请求。你现在页面刷新自动请求的原因就是默认给SWR传了固定key'uk'。要实现点击才触发,只要利用SWR的条件请求能力:当key为null/undefined等假值时,SWR会跳过请求,等你点击按钮把key设置为有效值后,SWR才会发起请求。
修改后的完整代码
import { useState } from 'react'; import useSWR from 'swr'; // 你的其他组件导入,比如NavBar、Hero、SearchBar、style等省略 const YourPage = () => { const [searchTerm, setSearchTerm] = useState(''); // 新增状态控制SWR请求的触发,初始为null不请求 const [searchKey, setSearchKey] = useState(null); const fetcher = async (key) => { // key就是你传入的搜索参数,这里可以拼接成你需要的请求地址 // 示例是用用户输入的searchTerm作为请求参数,你可以按需调整为固定值或者其他逻辑 const res = await fetch( `https://eu-central-1.aws.webhooks.mongodb-realm.com/api/client/v2.0/app/lottigully-jjrda/service/movies/incoming_webhook/movies?arg=${searchTerm || 'dexter'}` ); const data = await res.json(); return data; }; const { data, error, mutate } = useSWR(searchKey, fetcher); if (error) { return 'there was an error'; } // 调整Loading判断:只有已经发起请求且还没拿到数据时才显示Loading if (searchKey && !data) { return 'Loading'; } console.log(data); return ( <> <main> <div className={style.main_container}> <NavBar /> <Hero /> </div> <div className={style.search_container}> <SearchBar onChange={(e) => { setSearchTerm(e.target.value); }} /> </div> {/* 点击按钮时给searchKey赋值,触发SWR请求,调用mutate可强制刷新最新数据 */} <button onClick={() => { setSearchKey(searchTerm || 'uk'); mutate(); }}>Search!</button> {/* 这里可以加返回数据的渲染逻辑 */} {data && <div>请求结果:{JSON.stringify(data)}</div>} </main> </> ); } export default YourPage;
补充说明
- 如果需要每次点击按钮都重新发起最新的请求,不管key有没有变化,调用SWR返回的
mutate方法即可实现强制刷新 - fetcher的第一个参数会自动接收你传入的searchKey,你可以根据这个参数灵活拼接请求地址,不需要额外维护重复变量
内容的提问来源于stack exchange,提问作者Fabdol
相关产品推荐
相关产品推荐

