[英]Dispatch redux action in callback
I have started working with redux in react-native and I encountered problem, when I am dispatching
action in onLoadStart
function for Image component, the callback is firing and I see that action is called and I see Loading...
on screen, but when I am dispatching
in onLoadEnd
function nothing happen (callback loadEnd is not fired, app looks like frozen)
.我已经开始在 react-native 中使用 redux 并且遇到了问题,当我在onLoadStart
函数中为 Image 组件dispatching
动作时,回调正在触发,我看到该动作被调用,我在屏幕上看到Loading...
,但是当我在onLoadEnd
函数中dispatching
什么也没发生(callback loadEnd is not fired, app looks like frozen)
。 When I use console.log in both places code is working fine.当我在两个地方都使用 console.log 时,代码工作正常。 Could someone tell me what am I doing wrong?有人能告诉我我做错了什么吗?
class DisplayImage extends Component {
loadStart() {
this.props.iLoadingFunction(true);
}
loadEnd() { // <- this function is not fired
this.props.iLoadingFunction(false);
}
render() {
if (this.props.isLoading) {
return <Text>Loading…</Text>;
}
return (
<View>
<Image
source={{uri: 'https://test.com/image'}}
onLoadStart={this.loadStart.bind(this)}
onLoadEnd={this.loadEnd.bind(this)}
/>
</View>
);
}
}
const mapStateToProps = (state) => {
return {
isLoading: state.isLoading
};
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({ iLoadingFunction }, dispatch);
};
export default connect(mapStateToProps, mapDispatchToProps)(DisplayImage);
action and reducer动作和减速器
export function iLoadingFunction(bool) {
return {
type: 'IS_LOADING',
isLoading: bool
};
}
export function iLoadingFunction(state = false, action) {
switch (action.type) {
case 'IS_LOADING':
return action.isLoading;
default:
return state;
}
}
I think the issue is coming from the order that actions and renders are occurring in. Let's look at the render
function:我认为问题来自动作和渲染发生的顺序。让我们看看render
函数:
render() {
if (this.props.isLoading) {
return <Text>Loading…</Text>;
}
return (
<View>
<Image
source={{uri: 'https://test.com/image'}}
onLoadStart={this.loadStart.bind(this)}
onLoadEnd={this.loadEnd.bind(this)}
/>
</View>
);
}
The first time the component mounts this.props.isLoading
is false
, so the component renders组件第一次挂载this.props.isLoading
是false
,所以组件渲染
<View>
<Image
source={{uri: 'https://test.com/image'}}
onLoadStart={this.loadStart.bind(this)}
onLoadEnd={this.loadEnd.bind(this)}
/>
</View>
The Image
mounts, begins loading the image and dispatches this.props.iLoadingFunction(true)
. Image
挂载,开始加载图像并分派this.props.iLoadingFunction(true)
。
At this point isLoading
updates in the store are triggers a re-render of the component.此时isLoading
updates in the store 会触发组件的重新渲染。 This time this.props.isLoading
is true so the component renders这次this.props.isLoading
为真,所以组件渲染
<Text>Loading…</Text>
Now the original Image
has been removed from the hierarchy.现在原始Image
已从层次结构中删除。 I'm not actually sure if it continues to download the image, but the onLoadEnd
handler does not fire as the component expecting to handle it has been removed.我实际上不确定它是否会继续下载图像,但是onLoadEnd
处理程序不会触发,因为期望处理它的组件已被删除。
To get around this, I would leave the Image
in the hierarchy and just include or exclude the Text
based on this.props.isLoading
, like so为了解决这个问题,我会将Image
留在层次结构中,只包含或排除基于this.props.isLoading
的Text
,就像这样
render() {
return (
<View>
{ this.props.isLoading && <Text>Loading…</Text> }
<Image
source={{uri: 'https://test.com/image'}}
onLoadStart={this.loadStart.bind(this)}
onLoadEnd={this.loadEnd.bind(this)}
/>
</View>
);
}
The best solution to use callbackable-actions standardized actions.使用可回调动作标准化动作的最佳解决方案。 I recommend using the redux-cool package to do that我建议使用redux-cool包来做到这一点
npm install redux-cool
import {actionsCreator} from "redux-cool"
const callback = () => {
console.log("Hello, I am callback!!!")
}
const callbackable_action = actionsCreator.CALLBACKABLE.EXAMPLE(1, 2, 3, callback)
console.log(callbackable_action)
// {
// type: "CALLBACKABLE/EXAMPLE",
// args: [1, 2, 3],
// cb: [[Function callback]],
// _index: 1
// }
callbackable_action.cb()
// "Hello, I am callback!!!"
for more info, see: Redux Cool有关更多信息,请参阅: Redux Cool
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.