[关闭]
@fuxinghua 2018-11-21T06:51:01.000000Z 字数 3815 阅读 521

redux在react native中的高级应用篇

redux ReactNative


上一篇文章,介绍了redux在react native中的同步应用,也就是发出action, reducer函数重新计算state,然后更新视图View。

上面只是介绍了同步操作,在项目中异步操作该怎么办呢?所谓的异步操作,就是action发出后不是立即执行reducer,而是过一段时间执行reducer,然后更新视图。
如何解决这样的问题呢?我们需要用到中间件(middleware)
备注:图片来之阮一峰博客
此处输入图片的描述

中间件

本文是在react native项目中使用redux,当然redux也可以在其他框架中使用,这里只是介绍一下使用的方式。

action、reducer、api构建

Action构建如下:

export function login_doing(data) {
    return {
        type: types.LOGIN_IN_DOING,
        data
    }
}

export function login_done(data) {
    return {
        type: types.LOGIN_IN_DONE,
        data,
    }
}

export function login_err(data) {
    return {
        type: types.LOGIN_IN_ERROR,
        data,
    }
}

export function login_out(data) {
    return {
        type: types.LOGIN_IN_OUT,
        data,
    }
}

export function login_requ() {
    return loginService.getUserInfo()
}

reducer构建:
    export default function login(state = initState, action) {
    switch (action.type) {
        case loginTypes.LOGIN_IN_DOING:
            return {
                ...state,
                data: action.data
            }
        case loginTypes.LOGIN_IN_OUT:
            return {
                ...state,
                data: action.data
            }
        case loginTypes.LOGIN_IN_ERROR:
            return {
                ...state,
                data: action.data
            }
        case loginTypes.LOGIN_IN_DONE:
            action.data = JSON.parse(action.data)
            return {
                ...state,
                data: action.data
            }
        default:
            return state
    }
}

API构建:
    export function getUserInfo(params) {
    return dispatch => {
        dispatch(loginAction.login_doing(doingData));
        fetch('http://x.x.x.x:3001/') // 根据本机ip改写
            .then(res => {
                dispatch(loginAction.login_done(res._bodyText))
            })
            .catch(err => {
                loginAction.login_err(errData)
            })
    }
}

RN项目配置,中间件挂载

function configureStore(initialState) {
    return createStore(
        reducers,
        initialState,
        compose(applyMiddleware(thunk, createLogger))
    );
}

const store = configureStore();

export default store;

视图View构建

class Login extends Component {
    state = {
        text: ''
    }


    render() {
        // console.info('----->>>>>', JSON.stringify(this.props.store.getState().login))
        return <View>
            <TextInput
                style={{width: 220, height: 50, textAlign: 'center', borderColor: '#FF8247', borderWidth: 2}}
                placeholder={'input your name'}
                onChangeText={(text) => {
                    this.setState({text})
                }}
                value={this.state.text}
            />
            <View style={{flexDirection: 'row', justifyContent: 'space-between', marginTop: 20}}>
                <View style={{width: 100, height: 40, backgroundColor: '#FFEFD5', marginRight: 20}}>
                    <Button
                        onPress={() => {
                            this.props.store.dispatch(loginAction.login_requ())
                        }}
                        title="Login in"
                        color="#841584"
                    />
                </View>
                <View style={{width: 100, height: 40, backgroundColor: '#FFE1FF'}}>
                    <Button
                        color='red'
                        onPress={() => {
                            alert(2)
                        }}
                        title="Login out"
                    />
                </View>
            </View>
            <Text>{`username:${this.props.store.getState().login.data.user.name}`}</Text>
            <Text>{`age:${this.props.store.getState().login.data.user.age}`}</Text>
        </View>
    }

}

function mapStateToProps(store) {
    return {
        status: store.login.data.status,
        isSuccess: store.login.data.isSuccess,
        user: {
            name: store.login.data.user.name,
            id: store.login.data.user.id,
            phoneNumber: store.login.data.user.phoneNumber,
            age: store.login.data.user.age,
        }
    }
}

export default connect(mapStateToProps)(Login)

总结

通过以上构建就可以模拟redux异步使用了,具体参考:阮一峰redux讲解

上面代码中,所有中间件被放进了一个数组chain,然后嵌套执行,最后执行store.dispatch。可以看到,中间件内部(middlewareAPI)可以拿到getState和dispatch这两个方法。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注