Laravel 8如何处理React fetch请求实现无刷新筛选数据
现有代码问题梳理
- 你的React fetch回调中使用了
res.json(),但当前后端返回的是渲染好的HTML视图而非JSON格式,这一步会触发JSON解析错误。 - 如果你使用的是React函数式组件,回调中的
this.setState写法不适用,函数式组件需要用useState返回的更新方法修改状态。
可行解决方法
方案1:后端返回JSON数据(更符合前后端分离规范,推荐)
步骤1:修改Laravel控制器逻辑
将返回视图改为直接返回筛选后的文章JSON数据:
public function postBody(Request $request) { $chord = $request->get('chordId'); $posts = Post::join('categories', function ($builder) { $builder->on('categories.id', '=', 'posts.category_id'); }) ->where('name', '=', Str::before($chord, '.')) ->get(); // 直接返回JSON,不再渲染视图 return response()->json($posts); }
步骤2:修改React组件逻辑
首先在组件内声明存储文章列表的状态:
import { useState } from 'react'; // 组件内部初始化状态,初始值可设为页面首次加载的全量文章列表 const [posts, setPosts] = useState([]);
修改你的hideOnClick函数:
const url = '/category'; function hideOnClick(id) { setHide({value: id}) const body = { 'chordId' : id, } const requestMetadata = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }; fetch(url, requestMetadata) .then(res => res.json()) // 现在后端返回JSON可正常解析 .then(filteredPosts => { setPosts(filteredPosts) // 更新文章状态,React会自动重渲染列表 }) .catch(err => console.error('请求出错:', err)) }
步骤3:用状态渲染文章列表
直接在组件JSX中使用posts状态渲染内容,状态更新后页面会自动刷新列表,无需整页跳转:
<div className="post-list"> {posts.map(post => ( <div key={post.id} className="post-item"> <h3>{post.title}</h3> <p>{post.excerpt}</p> {/* 其他需要展示的文章字段 */} </div> ))} </div>
方案2:直接渲染后端返回的HTML(适合不想改动现有后端视图逻辑的场景)
如果不想修改后端的视图渲染代码,可以直接把后端返回的HTML插入到React组件的指定容器中:
步骤1:修改fetch处理逻辑
将res.json()改为res.text()获取HTML字符串:
// 声明状态存储返回的HTML内容 const [postListHtml, setPostListHtml] = useState(''); function hideOnClick(id) { setHide({value: id}) const body = { 'chordId' : id, } const requestMetadata = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }; fetch(url, requestMetadata) .then(res => res.text()) // 解析为HTML文本 .then(htmlStr => { setPostListHtml(htmlStr) }) .catch(err => console.error('请求出错:', err)) }
步骤2:在JSX中插入HTML
使用React的dangerouslySetInnerHTML属性渲染返回的HTML:
<div className="post-container" dangerouslySetInnerHTML={{__html: postListHtml}} ></div>
注意:该方案需要确保后端返回的HTML是安全的,不存在XSS注入风险。
内容的提问来源于stack exchange,提问作者Matthias
相关产品推荐
相关产品推荐

