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

能否将Promise作为Redux状态的一部分?业务场景需求问询

Absolutely, this approach is totally feasible and can make your questionnaire flow way cleaner—let’s break down why it works and how to implement it step by step.

Is Storing a Promise in Redux State Feasible?

Yes! While Redux’s official docs recommend keeping state serializable (since serialized state can be persisted, logged, or replayed), storing a Promise is totally acceptable for specific use cases like yours—where you need to defer handling an async result until a later point in your flow.

The key caveat here is that Promises can’t be serialized (so you’ll want to exclude them if you’re using state persistence tools like redux-persist), but for in-memory state management during your questionnaire flow, this pattern simplifies things drastically: you don’t have to manually track separate loading, error, and data states—you can leverage the Promise’s inherent pending/fulfilled/rejected status directly.

Implementation Walkthrough (With Redux Toolkit)

Redux Toolkit is the standard way to write Redux these days, so we’ll use it to build out your scenario: Q3 → trigger API call → store the Promise → use its result in Q7.

1. Define Your Redux Slice

First, create a slice to hold user answers and the API Promise:

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  userAnswers: {}, // Stores answers for Q1-Q6
  apiCallPromise: null, // Will hold the Promise from the Q3-triggered API call
};

const questionnaireSlice = createSlice({
  name: 'questionnaire',
  initialState,
  reducers: {
    // Save a user's answer to a specific question
    saveAnswer: (state, action) => {
      const { questionId, answer } = action.payload;
      state.userAnswers[questionId] = answer;
    },
    // Store the API call Promise in state
    setApiCallPromise: (state, action) => {
      state.apiCallPromise = action.payload;
    },
  },
});

export const { saveAnswer, setApiCallPromise } = questionnaireSlice.actions;
export default questionnaireSlice.reducer;

2. Trigger the API Call After Q3

In your Q3 component, when the user submits their answer, save it to state and dispatch the Promise from your API call:

import { useDispatch } from 'react-redux';
import { saveAnswer, setApiCallPromise } from './questionnaireSlice';
// Assume this is your API function that returns a Promise
import { fetchUserRelatedData } from './api';

const Q3Component = () => {
  const dispatch = useDispatch();

  const handleSubmit = (userAnswer) => {
    // Save Q3's answer first
    dispatch(saveAnswer({ questionId: 'Q3', answer: userAnswer }));
    
    // Trigger the API call and store the Promise in Redux
    const apiPromise = fetchUserRelatedData(userAnswer);
    dispatch(setApiCallPromise(apiPromise));
    
    // No need to handle the result here—we'll do that in Q7!
  };

  // Render your Q3 input/submit button here
  return (
    <div>
      <h2>Q3: [Your Question Text]</h2>
      {/* Input element for answer */}
      <button onClick={() => handleSubmit(userAnswer)}>Submit</button>
    </div>
  );
};

3. Use the Promise Result in Q7

In your Q7 component, pull the Promise from Redux state and handle its resolved/rejected status:

import { useSelector } from 'react-redux';
import { useState, useEffect } from 'react';

const Q7Component = () => {
  const apiPromise = useSelector(state => state.questionnaire.apiCallPromise);
  const [apiResult, setApiResult] = useState(null);
  const [apiError, setApiError] = useState(null);

  useEffect(() => {
    // Only process if we have a Promise that hasn't been handled yet
    if (apiPromise) {
      apiPromise
        .then(result => {
          setApiResult(result);
          // Optional: Clear the Promise if you don't need it anymore
          // dispatch(setApiCallPromise(null));
        })
        .catch(error => {
          setApiError(error);
          console.error('API call failed:', error);
        });
    }
  }, [apiPromise]);

  // Render Q7 content along with API result/error
  return (
    <div>
      <h2>Q7: [Your Question Text]</h2>
      
      {/* Show API result or error */}
      {apiError && <p className="error-message">Oops, failed to load data: {apiError.message}</p>}
      {apiResult && <div className="api-result">
        <h3>API Data:</h3>
        <p>{JSON.stringify(apiResult)}</p>
      </div>}
      
      {/* Q7 input/submit logic */}
    </div>
  );
};

Key Considerations

  • State Persistence: If you’re using redux-persist to save state to local storage, add apiCallPromise to the blacklist so it doesn’t get serialized (since Promises can’t be stored as JSON):
    import { persistReducer } from 'redux-persist';
    import storage from 'redux-persist/lib/storage';
    
    const persistConfig = {
      key: 'root',
      storage,
      blacklist: ['apiCallPromise'], // Exclude the Promise from persistence
    };
    
    const persistedReducer = persistReducer(persistConfig, questionnaireReducer);
    
  • Avoid Duplicate Calls: If users navigate back to Q3 and resubmit, this will overwrite the existing Promise. If you want to prevent that, add a check in the handleSubmit function to see if apiCallPromise already exists in state.
  • Uncaught Errors: Always include a .catch() when handling the Promise in Q7 to avoid uncaught rejection warnings.

内容的提问来源于stack exchange,提问作者Vladyslav Zavalykhatko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 10:10:41