[Error] [React] [Redux-Saga] saga 무한히 실행
Error
- 문제
- 상황 : mount하는 시점에 dispatch실행
- mount, action은 한번씩만 불렸지만, reducer과 saga는 여러번 호출됨
- 관련 코드
- Component (Layout.js)
import React, {Component} from 'react'; import { connect } from 'react-redux'; import '../assets/css/Contacts.css'; import {selectedContactAction} from '../Store/Actions/selectedContactAction' import {setContacts} from '../Store/Sagas/contactsSaga'; class Layout extends Component { async componentDidMount() { this.props.setContacts(); } render() { return ( <div className={'contacts'}> { this.props.contacts } </div> ); } } const mapStateToProps = (state) => ({ contacts : state.contacts }); const mapDispatchToProps = (Dispatch) => { return { setContacts : () => Dispatch(contactsSetAction()) } } export default connect(mapStateToProps,mapDispatchToProps)(Layout);
- Action Types (types.js)
export const contactsType = { CONTACTS_SET : 'CONTACTS_SET' }
- Action (contactsAction.js)
export const contactsSetAction = () => { return { type: contactsType.CONTACTS_SET } };
- Saga (contactsSaga.js)
export function* setContacts(){ try{ const response = yield call(fetchApi().getAll); yield put({type: contactsType.CONTACTS_SET, contacts : response.map(symbolizeObjectId)}); } catch (error) { yield put({type: contactsType.CONTACTS_SET, contacts : {}}) } finally { } } const saga = [ takeLatest(contactsType.CONTACTS_SET, contactsSaga.setContacts), ] export default saga;
- Reducer (contactReducer.js)
import { contactsType } from '../Actions/types'; const contactsReducer = (state = [], action) => { switch (action.type) { case contactsType.CONTACTS_SET: return action.contacts ? action.contacts : state; default: return state; } }; export default contactsReducer;
- Component (Layout.js)
Solve
-
Action, Saga 용 type과 reducer용 type을 나누기
- Action, Saga 용 :
CONTACTS_SET
- reducer 용 :
CONTACTS_SET_RESULT
- Action, Saga 용 :
-
변경한 코드 (
CONTACTS_SET_RESULT
추가)- Action Types (types.js)
export const contactsType = { CONTACTS_SET : 'CONTACTS_SET', //action, saga용 CONTACTS_SET_RESULT : 'CONTACTS_SET_RESULT' // reducer 용 }
- Saga (contactsSaga.js)
export function* setContacts(){ try{ const response = yield call(fetchApi().getAll); yield put({type: contactsType.CONTACTS_SET_RESULT, contacts : response.map(symbolizeObjectId)}); } catch (error) { yield put({type: contactsType.CONTACTS_SET_RESULT, contacts : {}}) } finally { } } const saga = [ takeLatest(contactsType.CONTACTS_SET, contactsSaga.setContacts), ] export default saga;
- Reducer (contactReducer.js)
import { contactsType } from '../Actions/types'; const contactsReducer = (state = [], action) => { switch (action.type) { case contactsType.CONTACTS_SET_RESULT: return action.contacts ? action.contacts : state; default: return state; } }; export default contactsReducer;
- Action Types (types.js)
핵심
무한히 saga를 호출하지 않게 하기 위해서 takeLatest
에서 지켜보는 type과 put
하는 type를 같게 하면 안된다.
- error 주요 코드
export function* setContacts(){ try{ const response = yield call(fetchApi().getAll); yield put({type: contactsType.CONTACTS_SET, contacts : response.map(symbolizeObjectId)}); } catch (error) { yield put({type: contactsType.CONTACTS_SET, contacts : {}}) } finally { } } // Action이랑 Saga 연결 const saga = [ takeLatest(contactsType.CONTACTS_SET, contactsSaga.setContacts) ]; export default saga;
put
과takeLatest
type 같음
- good 주요 코드
export function* setContacts(){ try{ const response = yield call(fetchApi().getAll); yield put({type: contactsType.CONTACTS_SET_RESULT, contacts : response.map(symbolizeObjectId)}); } catch (error) { yield put({type: contactsType.CONTACTS_SET_RESULT, contacts : {}}) } finally { } } // Action이랑 Saga 연결 const saga = [ takeLatest(contactsType.CONTACTS_SET, contactsSaga.setContacts) ]; export default saga;
put
과takeLatest
type 다름
Author And Source
이 문제에 관하여([Error] [React] [Redux-Saga] saga 무한히 실행), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@mong-head/Error-React-Redux-Saga-saga-무한히-실행저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)