使用redux-thunk時,更新state元件沒有重新渲染(render)
阿新 • • 發佈:2019-01-29
之前使用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,如有錯誤請在評論區中指出,謝謝啦~