gpt4 book ai didi

ajax - 调度执行 AJAX 请求的操作时出现无限循环 - ReactJS、Redux、Redux-saga

转载 作者:行者123 更新时间:2023-12-03 14:04:23 26 4
gpt4 key购买 nike

我正在尝试使用 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;

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>
);
}
}

我是 React 新手,对组件生命周期没有很好的掌握,但我相信每次 AJAX 请求完成并且“FETCH_MEAL_PLAN_SUCCESSFUL”案例在 reducer 中运行时都会调用 componentDidMount() 。

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( 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 多个请求: App in an infinite loop

我花了几个小时研究如何在更改路线后最好地从组件的 API 加载数据,但到目前为止我还没有成功。预先感谢您的帮助。

最佳答案

通常,组件应该运行一次componentDidMount,除非它被释放然后再次安装。如果它的 props 或 state 发生变化,那么 componentDidUpdate 将被触发。

因此,如果您遇到多个 componentDidMount,那么该组件很可能是作为子组件嵌套的(我猜您是从代码片段中做到的),然后当其父级(App)状态时或 Prop 更改,这将重新渲染其子项(包括 MealPlan)。因为您正在将 mealPlanmealPlan 从 redux 连接到 App。每当您调用 API 时,App 的 props 都会更新,从而导致其子级重新渲染,并导致 MealPlan 一次又一次触发 componentDidMount

我对 React 没有太多经验。但我没有看到你设置路线的方式。一种方法是在单独的文件中定义路由器,并像这样使用路由器(这使用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/react-boilerplate/react-boilerplate 。通过了解他们的做法,您可以实现您想要的目标

关于ajax - 调度执行 AJAX 请求的操作时出现无限循环 - ReactJS、Redux、Redux-saga,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43578143/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com