1. 程式人生 > >使用redux-thunk時,更新state元件沒有重新渲染(render)

使用redux-thunk時,更新state元件沒有重新渲染(render)

之前使用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,如有錯誤請在評論區中指出,謝謝啦~