我正在尝试使用redux-saga和axios加载组件的数据,但我一直在获得无限的循环。这些是相关组件:
app.js
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;
fealplan.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>
);
}
}
我是新手的反应,我对组件生命周期没有很好的掌握,但是我相信每当AJAX请求完成时,ComponentDidMount((都会被调用,并且在还原器中运行'fetch_meal_plan_succescessful'案例。
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);
}
fealplan.js(reducer(
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;
如果我不停止应用程序,它将继续提出请求。在此测试中,它提出了4,200多个请求:在无限循环中的应用
我花了几个小时研究如何在更改路线后从API中最大程度地加载组件的数据,到目前为止,我一直没有成功。预先感谢您的帮助。
通常,组件应运行componentDidMount
一次,除非将其划分然后再次安装。如果其道具或状态更改,则将发射componentDidUpdate
。
因此,如果您遇到了多个componentDidMount
,那么该组件很可能是小时候嵌套的(我想您是从代码片段中使用的(,然后当其父母的(app(状态或道具更改时,这将重新 - 赋予孩子(包括餐制(。因为您正在连接mealPlan
&amp;mealPlan
从Redux到App。每当您致电API时,App的道具都会被更新,从而导致其孩子重新渲染,并一次又一次地触发餐策 componentDidMount
。
我不是反应的超级经验。但是我还没有看到您设置路线的方式。一种方法是在单独的文件中定义路由器,然后使用这样的路由器(这是不是使用React-Router的代码 - 拆分功能(:
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/reaect-boilerplate/reaect-boilerplate。通过查看他们的工作方式,您可以实现自己想要的