2017-04-24 4 views
0

redux-saga 및 axios를 사용하여 구성 요소의 데이터를로드하려고하지만 계속 무한 루프가 발생합니다. 다음은 관련 구성 요소 : App.jsAJAX 요청을 수행하는 작업을 디스 패칭 할 때 무한 루프 - ReactJS, Redux, Redux-saga

class App extends React.Component { 
    render() { 
    return (
     <div className="app"> 
     <header> 
      <div className="pure-u-1 pure-u-sm-1-3"> 

      </div> 
      <nav className="pure-u-1 pure-u-sm-2-3"> 
      <ul> 
       <li><Link to="/meal-plans">Meal Plans</Link></li> 
      </ul> 
      </nav> 
     </header> 
     <main> 
      <div className="view-area"> 
      <Switch> 
       <Route exact path="/" component={() => <DashBoard {...this.props} />} /> 
       <Route exact path="/meal-plans" component={() => <MealPlansContainer {...this.props} />} /> 
       <Route path="/meal-plans/:id" component={props => <MealPlan {...this.props} {...props} />} /> 
      </Switch> 
      </div> 
     </main> 
     </div> 
    ) 
    } 
} 

function mapStateToProps(state) { 
    return { 
    app: state.app, 
    mealPlan: state.mealPlan, 
    mealPlans: state.mealPlans, 
    } 
} 

function mapDispatchToProps(dispatch) { 
    return bindActionCreators(actionCreators, dispatch); 
} 

App = withRouter(connect(mapStateToProps, mapDispatchToProps)(App)); 

export default App; 

MealPlan.js

class MealPlan extends React.Component { 
    componentDidMount() { 
     let id = this.props.match.params.id 
     this.props.fetchMealPlan(id); 
    } 
    render() { 
     return (
      <div className="meal-plan pure-g box"> 
       <div className="pure-u-1"> 
        <p>Future Meal Plan Page</p> 
        <LoadingSpinner show={true} /> 
       </div> 
      </div> 
     ); 
    } 
} 

내가 반응하는 새로운 그리고 난에 잘 이해가없는 구성 요소 수명주기,하지만 나는 componentDidMount() AJAX 요청이 완료되고 'FETCH_MEAL_PLAN_SUCCESSFUL'사건이 감속기에서 실행될 때마다 호출되고 있다고 생각합니다.

actionCreators.js

export function fetchMealPlan(id) { 
    return { 
    type: 'FETCH_MEAL_PLAN', 
    id 
    } 
} 

export function fetchMealPlanSuccessful(data) { 
    return { 
    type: 'FETCH_MEAL_PLAN_SUCCESSFUL', 
    data 
    } 
} 

export function fetchMealPlanFail(message) { 
    return { 
    type: 'FETCH_MEAL_PLAN_FAIL', 
    message 
    } 
} 

sagas.js

function* fetchMealPlan(action) { 
    try { 
    const mealPlan = yield call(api.get, '/meal_plans/' + action.id); 
    yield put(fetchMealPlanSuccessful(mealPlan.data)); 
    } catch (e) { 
    yield put(fetchMealPlanFail(e.message)); 
    } 
} 

function* watchFetchMealPlan() { 
    yield takeLatest('FETCH_MEAL_PLAN', fetchMealPlan); 
} 

mealPlan.js (감속기)

function mealPlan(state = {}, action) { 
    switch(action.type) { 
    case 'FETCH_MEAL_PLAN': 
     return state; 
    case 'FETCH_MEAL_PLAN_FAIL': 
     return state; 
    case 'FETCH_MEAL_PLAN_SUCCESSFUL': 
     state = Object.assign({}, action.data); 
     return state; 
     break; 
    default: 
     return state; 
    } 
} 

export default mealPlan; 

만약 내가하지의 앱 상단에서 요청을 계속합니다. 연구 App in an infinite loop

내가 소비 한 시간을 어떻게 경로를 변경하고 지금까지 내가 성공하지 한 후 구성 요소에 대한 내 API에서 출발하는 가장 부하 데이터에 :이 테스트에서는 4,200+ 요청을했다. 당신의 도움에 미리 감사드립니다.

답변

1

일반적으로 구성 요소는 할당 해제 된 다음 다시 탑재되지 않는 한 componentDidMount을 한 번 실행해야합니다. 소도시 또는 주를 변경하면 componentDidUpdate이 (가) 해고됩니다.

여러 componentDidMount이 발생하는 경우이 구성 요소는 하위 (코드 스 니펫에서 가져온 것으로 추정 됨)에 중첩되어 있으며 부모의 (App) 상태 또는 소품이 변경되면 그 자식 (MealPlan 포함)을 다시 렌더링합니다. 귀하가 연결하기 때문에 mealPlan & mealPlan redux에서 App. API를 호출 할 때마다 App의 소품이 업데이트되어 자식이 다시 렌더링되고 MealPlan 트리거 componentDidMount이 계속해서 다시 발생합니다.

저는 React에 대한 경험이 많지 않습니다. 그러나 나는 당신이 길을 세우는 방식을 보지 못했습니다. 한 가지 방법은 (이 반응 라우터의 코드 분할 기능을 사용 하지입니다) 별도의 파일에 라우터를 정의하고이 같은 공유기를 사용하는 것입니다 :

const router = (
    <Router history={browserHistory}> 
    <Route path="/" component={App}> 
    <Route path="/meal-plans" component={MealPlan} /> 
    </Route> 
    </Router> 
) 

ReactDOM.render(
    <Provider store={createStoreWithMiddleware(reducers)}> // react-redux provider 
     { router } 
    </Provider>, 
    document.querySelector('#main')); 

당신 싶어 코드 분할 할 경우, 당신이 redux-sagas를 사용하고 있기 때문에 좋은 템플릿은 https://github.com/react-boilerplate/react-boilerplate입니다. 그들이하는 방식을 살펴봄으로써 원하는 것을 얻을 수 있습니다.

+0

자세한 답변을 부탁드립니다. 내 주요 애플 리케이션 구성 요소에 redux 연결되는 문제에 대해 당신이 정확하다고 생각합니다. 컨테이너 구성 요소를 사용하여 데이터를로드하지 못했습니다. 이 리소스는 앱 구성 방법을 이해하는 데 유용하다는 것을 알게되었습니다. [컨테이너 연결] (https : // egghead.io/lessons/javascript-redux-generating-containers-connected-from-react-redux-visibletodolist) 및 [React + Redux 컨테이너 패턴] (http://www.thegreatcodeadventure.com/the-react-plus-redux -container-pattern /). – RonquilloAeon

+0

'MealPlan' 컴포넌트를'App' 대신 redux에 연결하면 제 문제가 해결되었습니다. 연구하고 고생하는 데 너무 많은 시간을 보냈습니다. 당신의 도움에 감사드립니다! – RonquilloAeon