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

React组件中react-loader-spinner不显示:请求时无加载状态

解决react-loader-spinner在API请求期间不显示的问题

你的代码核心问题是加载状态的设置时机完全颠倒,导致加载动画永远不会在请求等待阶段显示:

  • 你在API请求完成的then回调里才把isLoading设为true,这时候请求已经结束,加载动画根本没机会出现
  • 当前isLoading为true时,组件只返回加载动画,但这时候请求已经完成,逻辑完全反了

修正步骤:

  1. 发起请求前立即设置加载状态:在调用openai.createCompletion之前,先通过setState把isLoading设为true,触发加载动画显示
  2. 请求结束后关闭加载状态:在then(请求成功)和catch(请求失败)回调里,把isLoading设为false,同时更新数据或处理错误
  3. 错误处理:添加catch捕获请求异常,避免请求失败后页面一直处于加载状态

修改后的完整代码:

import React from "react";
import { Component} from "react";
import { Container, Form, Button, Card, FormGroup, FormLabel, FormControl  } from 'react-bootstrap'
import { ThreeDots } from 'react-loader-spinner'

const { Configuration, OpenAIApi } = require('openai');

class AppGenerator extends Component {
    constructor() {
        super()
        this.state = {
            isLoading: false,
            heading: '',
            response: '',
            error: '' // 新增错误状态,用于显示请求失败信息
        }
    }

    onFormSubmit = async e => {
        e.preventDefault()

        const formData = new FormData(e.target),
        formDataObj = Object.fromEntries(formData.entries())
        console.log(formDataObj.suggestion)

        // 修改点1:发起请求前设置加载状态为true
        this.setState({ isLoading: true, error: '' });

        const configuration = new Configuration({
            apiKey: 'somekey',
        });
        const openai = new OpenAIApi(configuration);

        openai.createCompletion({
            model: 'text-davinci-003', 
            prompt: `Write the blog about ${formDataObj.suggestion} and be very specific about it with a minimum of 1500 words`,
            temperature: 1,
            max_tokens: 2000,
            top_p: 1,
            frequency_penalty: 0,
            presence_penalty:0,
        })
        .then((response) => {
            // 修改点2:请求成功后关闭加载状态,更新数据
            this.setState({
                isLoading: false,
                heading: `Suggestion for: ${formDataObj.suggestion}`,
                response: `${response.data.choices[0].text}`,
            })
        })
        // 修改点3:添加错误捕获,关闭加载状态并记录错误信息
        .catch((err) => {
            this.setState({
                isLoading: false,
                error: '请求失败,请稍后重试'
            });
            console.error('API请求错误:', err);
        });
    }

    render() {
        const {isLoading, heading, response, error} = this.state;

        if (isLoading) {
            return <ThreeDots height="80" width="80" radius="9" color="green" ariaLabel="loading"/>
        }

        return(
            <div>
                <Container>
                    <br/>
                    <h2 style={{color: '#fff'}}>Blog Post Suggestion</h2>
                    <br/>
                    <Form onSubmit={this.onFormSubmit}>
                        <FormGroup className="mb-3" controlId="formBasicEmail">
                            <FormLabel style={{color: '#fff'}}>What would you us to write about?</FormLabel>
                            <FormControl
                                type = 'text'
                                name = 'suggestion'
                                placeholder= 'ie: How artificial intelligence will change the world'
                            />
                             <Form.Text className="text-muted">
                                Enter as much information as possible.
                            </Form.Text>
                        </FormGroup>
                        <Button id="button" variant="primary" size='lg' type="submit" className="button-submit">
                            Create Blog Post
                        </Button>
                    </Form>

                    {/* 显示错误信息 */}
                    {error && <p style={{color: 'red', marginTop: '1rem'}}>{error}</p>}

                    <br/>
                    <br/>

                    <Card style={{border: 'none'}}>
                        <Card.Body style={{background: '#212529'}}>
                            <Card.Title style={{color: '#fff', background: '#212529'}}><h2>{heading}</h2></Card.Title>
                            <br/>
                            <Card.Text style={{color: '#fff', background: '#212529'}}><p>{response}</p></Card.Text>
                        </Card.Body>
                    </Card>
                </Container>
                <br/>
                <br/>
                <br/>
                <br/>
                <br/>
                <br/>
                <br/>
                <br/>
            </div>
        )
    }
}

export default AppGenerator

可选优化:

如果不想在加载时替换整个页面,可以把加载动画嵌入到页面中(比如按钮位置或结果区域),而不是直接返回加载组件。例如修改render部分:

render() {
    const {isLoading, heading, response, error} = this.state;

    return(
        <div>
            <Container>
                <br/>
                <h2 style={{color: '#fff'}}>Blog Post Suggestion</h2>
                <br/>
                <Form onSubmit={this.onFormSubmit}>
                    <FormGroup className="mb-3" controlId="formBasicEmail">
                        <FormLabel style={{color: '#fff'}}>What would you us to write about?</FormLabel>
                        <FormControl
                            type = 'text'
                            name = 'suggestion'
                            placeholder= 'ie: How artificial intelligence will change the world'
                            disabled={isLoading} // 加载时禁用输入框
                        />
                         <Form.Text className="text-muted">
                            Enter as much information as possible.
                        </Form.Text>
                    </FormGroup>
                    <Button 
                        id="button" 
                        variant="primary" 
                        size='lg' 
                        type="submit" 
                        className="button-submit"
                        disabled={isLoading} // 加载时禁用按钮,防止重复提交
                    >
                        {isLoading ? <ThreeDots height="20" width="20" radius="3" color="#fff" ariaLabel="loading"/> : 'Create Blog Post'}
                    </Button>
                </Form>

                {error && <p style={{color: 'red', marginTop: '1rem'}}>{error}</p>}

                <br/>
                <br/>

                {isLoading ? (
                    <div style={{display: 'flex', justifyContent: 'center', padding: '2rem'}}>
                        <ThreeDots height="80" width="80" radius="9" color="green" ariaLabel="loading"/>
                    </div>
                ) : (
                    <Card style={{border: 'none'}}>
                        <Card.Body style={{background: '#212529'}}>
                            <Card.Title style={{color: '#fff', background: '#212529'}}><h2>{heading}</h2></Card.Title>
                            <br/>
                            <Card.Text style={{color: '#fff', background: '#212529'}}><p>{response}</p></Card.Text>
                        </Card.Body>
                    </Card>
                )}
            </Container>
            <br/>
            <br/>
            <br/>
            <br/>
            <br/>
            <br/>
            <br/>
            <br/>
        </div>
    )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 09:50:17