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

如何将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 15:57:00