使用redux-thunk时,更新state组件没有重新渲染(render)

本文介绍如何使用Redux-Thunk处理异步操作,并确保组件能够响应状态变化进行重新渲染。通过详细示例说明了如何设置action、reducer以及组件的状态处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前使用redux-thunk异步访问服务器时,发现state更新了,组件却并没有重新渲染,和以前的代码对照了很久之后,发现原因在于偷懒没写status。

在异步action对应的reducer里面,除了改变相应state之外,还应该改变status,明确的告诉组件数据获取到了,状态树和以前不同了,再进行重新渲染。
使用redux-thunk的正确姿势举例如下:

//actionType.js
const GET_FM_STARTED = 'FM/GET_STAETED';
const GET_FM_SUCCESS = 'FM/GET_SUCCESS';
const GET_FM_FAILURE = 'FM/GET_FAILURE';
//status.js
const Status = {
    LOADING: 'loading',
    SUCCESS: 'success',
    FAILURE: 'failure'
}
//action.js

const getFMStarted = () => ({
    type: GET_FM_STARTED
});

const getFMSuccess = (result, areaUid) => {
    result = JSON.parse(result);
    result.data = eval(result.data);
    return {
        type: GET_FM_SUCCESS,
        result: result,
        areaUid: areaUid
    }
};

const getFMFailure = (error) => ({
    type: GET_FM_FAILURE,
    error
});

let FMNextId = 0;
const getFM = (areaUid) => {
    return (dispatch) => {
        const url = `/Area/GetFlowMeterByAreaUid?areaUid=${areaUid}`;    //(Guid areaUid)`
        const seqId = ++FMNextId;
        const dispatchIfVaild = (action) => {
            if (seqId === FMNextId) {
                return dispatch(action);
            }
        }
        dispatchIfVaild(getFMStarted());
        fetch(url).then((response) => {
            if (response.status !== 200) {
                throw new Error('Fail to get response with status ' + response.status);
            }
            response.json().then((responseJson) => {
                dispatchIfVaild(getFMSuccess(responseJson, areaUid));
            }).catch((error) => {
                console.error(error);
                dispatchIfVaild(getFMFailure(error));
            });
        }).catch((error) => {
            console.log(error);
            dispatchIfVaild(getFMFailure(error));
        })
    };
}
//Components/Card.js
class Card extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        const { status, warn, header } = this.props;
        if (!warn) { return null; }
        console.log(status);
        let content = null;
        switch (status) {
            case Status.LOADING: {
                content = <h3>信息加载中...</h3>;
                break;
            }
            case Status.SUCCESS: {
                content = this.props.children;
                break;
            }
            case Status.FAILURE: {
                content = <h3>信息加载失败,请重试</h3>;
                break;
            }
            case 'init': {
                content = <h3>{this.props.init || '信息加载中...' }</h3>;
            }
            default: {
                content = <h3>{this.props.init || '信息加载中...'}</h3>;
                //throw new Error('unexpected status ' + status);
            }
        }
        return (
            <div className="devices">
                <article className="ibox">
                    <header className="ibox-title">
                        <Header header={header} />
                    </header>
                    <article className='ibox-content'>
                        {content}
                    </article>
                </article>
            </div >
        );
    }
}

博主也是刚接触react,如有错误请在评论区中指出,谢谢啦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值