reactjs - yield takeEvery 不断被调用
问题描述
我正在尝试学习 react-redux-saga;所以我正在构建一个简单的应用程序,它调用一个随机的用户配置文件 api 并显示它。基本上,当用户点击“下一张图片”按钮时,它应该进行 REST 调用并检索下一张图片。我能够进行 API 调用并显示信息,但它会不断地无限调用 API,并且尽管没有单击任何内容,数据也会不断变化。这是我的代码:
App.js(父组件)
class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="App">
<p className="App-intro">
{ this.props.user !== undefined ? <ImageGenerator user={this.props.user}></ImageGenerator> : <span></span>}
</p>
</div>
);
}
}
const mapStateToProps = state => {
return { user: state.value };
};
const mapDispatchToProps = dispatch => {
return {
getNewImage: () =>
dispatch({
type: NEXT_IMAGE
})
}
};
export default connect(mapStateToProps, mapDispatchToProps)(App);
该组件是进行 API 调用并通过 user 属性将信息传递到 ImageGenerator 组件的组件。我注意到当我注释掉 ImageGenerator 行时,API 调用停止。我还在 mapDispatchToProps 中输入了一个日志,以验证它是否只调度 NEXT_IMAGE 操作一次。
以下是我的行动:
export const NEXT_IMAGE = function() { return { type: "NEXT_IMAGE" } };
export const fetchFailed = function(error) { return { type: "FETCH_FAILED", value: error } };
export const setImage = function(data) { return {type: "SET_IMAGE", value: data} };
这是我的传奇:
export function* fetchImage() {
try {
const response = yield call(fetch, 'https://randomuser.me/api/');
const responseBody = yield response.json();
console.log("QWERT", responseBody.results);
yield put(setImage(responseBody.results[0]));
} catch (e) {
yield put(fetchFailed(e));
}
return;
}
export function* watchNextImage() {
yield takeEvery(NEXT_IMAGE, fetchImage);
}
export default function* rootSaga() {
yield all([
fetchImage(),
watchNextImage()
])
}
我怀疑这与我传奇中的 watchNextImage 函数有关。这就是在 NEXT_IMAGE 操作上放置一个手表,然后在它发生时调用 fetchImage 的东西。但是,我不明白如果我只分派 NEXT_IMAGE 操作一次,它为什么会继续调用 fetchImage ......
这是我的减速器和我的 ImageGenerator - 这里可能没什么有趣的:
减速器.js:
const rootReducer = (state = {}, action) => {
switch(action.type) {
case NEXT_IMAGE: {
return Object.assign({}, state, action)
}
case "FETCH_FAILED": {
return state;
}
case "SET_IMAGE": {
return Object.assign({}, state, action)
}
default: {
return state;
}
}
};
export default rootReducer;
ImageGenerator.js:
class ImageGenerator extends Component {
constructor(props) {
super(props);
}
render() {
let user = this.props.user;
console.log("USer", user);
return (
<div>
Name: {user.name.first} {user.name.last} <br />
Phone: {user.phone} <br />
Date of Birth: {user.dob.date} <br/>
Age: {user.dob.age} <br/>
Email: {user.email} <br />
Gender: {user.gender} <br/>
City: {user.location.city } <br />
State: {user.location.State } <br />
Street: {user.location.street } <br />
<img src={user.picture.medium} alt="No Image Found"/>
<button onClick={NEXT_IMAGE}>New Image</button>
<button>Add to Favorites</button>
</div>
)
}
}
export default ImageGenerator
解决方案
更改rootSaga
为仅yield
watchNextImage
(传奇)。你不需要yield
fetchImage
(副作用)。
export default function* rootSaga() {
yield all([
spawn(watchNextImage)
])
}
之后,您只需在组件中正确连接您的操作。
推荐阅读
- sql - 如何使用 like 语句检查 where 子句中 json 数组的每个项目
- amazon-ses - 批量发送时如何在 AWS SES 电子邮件中包含唯一变量?
- loopbackjs - Loopback4 DefaultTransactionalRepository 不起作用
- .net-core - 相当于 Tag Helper .NET Core 中的 Telerik Html.Kendo().Grid(Model)?
- javascript - 如何在不破坏任何功能的情况下使用 barba.js 运行其他 JS 文件
- azure - Azure Function 混合连接到共享文件夹
- mysql - 如何使用 COUNT(*) 在 GROUP BY 中包含不存在的值?
- c - 返回值与预期不符。AVR C 计算
- javascript - 使用javascript,jquery的时差
- regex - 正则表达式 - 找到可能的最短匹配