如何将redux-thunk store中的JSON数据渲染到HTML元素并优化代码
实现渲染&代码优化方案
一、核心修改步骤(实现数据渲染)
1. 修复现有代码bug
首先你现有actions.js存在两处明显问题:
- 全局
url变量未定义,需要补上你的Rails接口地址http://127.0.0.1:3000/questions createQuestion的请求配置写错了,fetch的请求体字段是body不是question,还需要补充请求头声明JSON格式
修复后的actions.js代码:
// 先定义接口地址 const API_URL = "http://127.0.0.1:3000/questions" // 定义action类型常量避免拼写错误 export const GOT_QUIZ = "GOT_QUIZ" export const ADD_QUIZ = "ADD_QUIZ" export const getQuestion = (question) => ({type: GOT_QUIZ, payload: question}) export const addQuestion = (question) => ({type: ADD_QUIZ, payload: question}) export const fetchQuestion = () => { return (dispatch) => { fetch(API_URL) .then(resp => resp.json()) .then(question => { dispatch(getQuestion(question)) }) // 补充错误处理 .catch(err => console.error('拉取题目失败:', err)) } } export const createQuestion = (question) => { return (dispatch) => { const configObj = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(question) } fetch(API_URL, configObj) .then(resp => resp.json()) .then(json => { // 新建成功后更新store dispatch(addQuestion(json)) }) .catch(err => console.error('新建题目失败:', err)) } }
对应的reducer.js补充新增题目的处理逻辑:
import { GOT_QUIZ, ADD_QUIZ } from '../actions/actions' export default function quizReducer(state = {questionBank: []}, action){ switch (action.type){ case GOT_QUIZ: return {...state, questionBank: action.payload} case ADD_QUIZ: return {...state, questionBank: [...state.questionBank, action.payload]} default: return state } }
2. 调整App.js,移除冗余的原生fetch请求
你已经配置了Redux+thunk,不需要在组件内直接调用fetch,走Redux的action流程即可:
import React from "react"; import {BrowserRouter as Router, Switch, Route} from 'react-router-dom' import "./assets/style.css"; import Quiz from "./components/quiz" import Home from "./components/home"; import Result from "./components/Result"; function App() { return ( <div className="App"> <Router> <Switch > <Route exact path="/"> <Home /> </Route> <Route exact path="/quiz"> <Quiz/> </Route> <Route exact path="/result"> <Result /> </Route> </Switch> </Router> </div> ); } export default App
3. 在需要展示题目的组件(以Quiz组件为例)中获取store数据并渲染
在组件内用useDispatch触发拉取题目的action,用useSelector获取store中存储的题目列表,直接渲染即可:
// Quiz组件示例代码 import React, { useEffect } from 'react' import { useDispatch, useSelector } from 'react-redux' import { fetchQuestion } from '../store/actions/actions' const Quiz = () => { const dispatch = useDispatch() // 从store获取题目列表 const questionBank = useSelector(state => state.questionBank) useEffect(() => { // 进入组件时拉取题目 dispatch(fetchQuestion()) }, [dispatch]) return ( <div className="quiz-container"> <h2>答题页</h2> {/* 遍历渲染题目列表 */} {questionBank.map((question, index) => ( <div key={question.id || index} className="question-item"> <p>第{index+1}题:{question.title}</p> {/* 按需渲染选项、答题控件等 */} </div> ))} </div> ) } export default Quiz
二、其他优化建议
- 开启Redux DevTools支持,方便调试状态变化:创建store时修改为
const store = createStore(quizReducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(), applyMiddleware(thunk)) - 后续业务复杂后可以拆分reducer、用Redux Toolkit简化Redux模板代码
- 接口请求可以统一封装,增加loading、错误提示等通用逻辑
- 给路由增加懒加载配置,减少首屏加载体积
内容的提问来源于stack exchange,提问作者Kiana
相关产品推荐
相关产品推荐

