我正在使用React + Redux + Redux-Saga。
在我的情况下,我正在调用2个api-用于Config和用于Data(在提取Config之后)
调用数据时出现问题。简而言之:
这有效:
TestRoute.jsx文件(尚未使用isConfig
):
import React from 'react';
import { connect } from 'react-redux';
import TestComponent from '../components/Test';
const Test = ({ isConfig }) => <div>
<TestComponent />
<TestComponent />
<TestComponent />
<TestComponent />
</div>
const mapStateToProps = state => ({
isConfig: !!state.config.payload.tenantId
});
export default connect(mapStateToProps)(Test);
TestComponent.jsx
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { dataRequestInit } from '../state/actions/data';
class Test extends Component {
componentDidMount() {
this.props.dataRequestInit('https://data/api/url');
}
render() {
return <p>hello</p>;
}
}
const mapStateToProps = state => ({})
export default connect(
mapStateToProps,
{ dataRequestInit }
)(Test);
Saga文件:
const getIsFetching = (state, url) => state.data.isFetching.includes(url);
function* fetchData(url) {
try {
const isFetching = yield select(getIsFetching, url);
if (!isFetching) {
yield put(actions.fetchDataIsFetching(url));
const response = yield call(api, url);
console.log('response', response);
}
} catch (err) {
console.log('handle error', err);
}
}
export default function* DataSaga() {
yield takeEvery(actionTypes.FETCH_DATA_INIT, fetchData);
}
在这种情况下,一切都很好-第一个调用设置为isFetching,并且正在执行一个api请求。 Redux DevTools view
但是如果我重新创建Route文件以开始使用isConfig标志并有条件地渲染TestComponents:
const Test = ({ isConfig }) =>
isConfig && (
<div>
<TestComponent />
<TestComponent />
<TestComponent />
<TestComponent />
</div>
);
一切都变得疯狂,并且向服务器发送了4个api调用。那是因为开始Redux DevTools view而不是像预期的那样,先启动4x DATA / FETCH_INIT动作,然后再执行4x DATA / SET_IS_FETCHING动作:1x DATA / FETCH_INIT 1x DATA / SET_IS_FETCHING 3x DATA / FETCH_INIT像以前一样。
有人可以向我解释为什么会这样吗?我在这里缺少什么,以及可能如何解决该问题?
答案 0 :(得分:0)
我可以看到您的问题,您将同一组件安装了4次,如下所示:
componentDidMount() {
this.props.dataRequestInit('https://data/api/url');
}
然后渲染4次:
<TestComponent />
<TestComponent />
<TestComponent />
<TestComponent />
这将为每个组件触发一个单独的函数调用实例,具有用于“ isFetching”的变量不会阻止其他组件进行API调用。
还要注意的另一件事是,如果此组件需要渲染4次,并且它们都需要相同的数据,则最好将控制权交给父组件,一次获取数据,然后将其传递给每个实例中的组件,如下所示:
<TestComponent data={state.data}/>
此外,此操作的减速器情况应如下所示:
switch (action.type) {
case AUTH_REQUEST:
return {
...state
}
具有传播运算符的状态变量,它使状态保持先前的操作,在您的情况下为获取变量。
希望这会有所帮助
劳埃德