美文网首页
React Native+Redux设计模式

React Native+Redux设计模式

作者: 猎手Andy | 来源:发表于2018-09-10 16:31 被阅读0次

    本文从学习的角度,分析整理React Native项目中运用Redux的设计模式。
    发现整个项目几乎都是一样的模式,作为原生开发的工程师,理解此模式非常有必要。
    注:本文是英文写成,简单加了点中文,将就着看吧。

    1. Component(SwitchComponent.js)

    • props.data
    • props.actions
    class Switch extends Component{
        constructor(props) {
          super(props);
        }
        render(){
            return (
                <View style = {style.container}>
                   <View style = {style.header}>
                      <View style={style.headerName}>
                          <Text style={style.headerNameTitle}>Hostname</Text>
                          <Text style={style.headerNameTitleText}>{this.props.detail.hostname}</Text>
                      </View>
                   </View>
                </View>
            )
        }
    }
    

    2. Container (SwitchScreen.js)

    绑定props和reducer的state

    props <===> state

    build props to interactive with state

    render a Component

    import Switch from "../../components/switch/switchComponent";
    render(){
            const { navigation } = this.props;
            return (        
              <View style={{minHeight:SCREEN_HEIGHT-100}}>
                <Switch {...this.props}/> //assign this.props to Switch component
              </View>
            )
        }
    

    以下是绑定三件套

    • mapStateToProps

    Mapping reducers state to component props(this.props.detail) 建立映射关系

    function mapStateToProps(state) {
      return {
        detail: state.manage.switchDetail.data,
        isFetching: state.manage.switchDetail.isFetching,
        error:state.manage.switchDetail.error
      }
    }
    
    • mapDispatchToProps

    Mapping Dispatch Actions to component props(this.props.actions) 建立Action映射关系

    import manageAction from '../../actions';
    
    function mapDispatchToProps(dispatch){
      return {
            actions: bindActionCreators(manageAction.device, dispatch)
        };
    }
    
    • connect

    Exported to redux 暴露让redux知道,这里是真正的注册

    export default connect(mapStateToProps, mapDispatchToProps)(SwitchScreen);
    

    3. Reducer (switchDetail.js)

    Right part(state) of mapStateToProps (state.manage.switchDetail.data)

    看看state.manage.switchDetail.data是从哪里来的?

    function mapStateToProps(state) {
      return {
        detail: state.manage.switchDetail.data,
        isFetching: state.manage.switchDetail.isFetching,
        error:state.manage.switchDetail.error
      }
    }
    

    入口reducer

    App.js (root reducer)

    import {Provider} from 'react-redux';
    import {createStore, applyMiddleware} from 'redux';
    import thunk from 'redux-thunk';
    import reducer from './src/reducers';//root reducers 
    import RootStack from './src/router';
    import NavigationService from './src/api/navigationService';
    
    let store = createStore(reducer,applyMiddleware(thunk));
    
    export default class App extends Component {
      render() {
        console.disableYellowBox = true;
        return (
          <Provider store={store}>
            <RootStack ref={navigatorRef => {
              NavigationService.setTopLevelNavigator(navigatorRef);
            }} />
          </Provider>
        );
      }
    }
    
    

    import reducer from './src/reducers';//root reducers=>reducers/index.js

    import manage from '../features/manage/reducers';
    export default combineReducers({
      auth,
      manage,
      form: formReducer
    });
    

    => manage (state.manage)

    import switchDetail from './switchDetail';
    export default combineReducers({
      switchDetail,
      portDetail,
    });
    

    =>switchDetail (state.manage.switchDetail)

    //reducer
    const initialState = Immutable({
      isFetching: false,
      error: false,
      data: {},  
      noRadio:false,
      noClients:false,
      noWLAN:false
    });
    export default function switchDetail(state = initialState, action){
      switch (action.type) {
        case aTypes.LOAD_SWITCH:
          return {
            ...initialState,
            isFetching: true,
            data: {} //--> state.manage.switchDetail.data
          };
        case aTypes.LOAD_SWITCH_SUCCESS:
        let hasRadio = Object.keys(action.data).length && !!action.data.radios&& action.data.radios.length;
        let hasClients = Object.keys(action.data).length && !!action.data.clients&& action.data.clients.length;
        let hasWLAN = Object.keys(action.data).length && !!action.data.wlans&& action.data.wlans.length;
        return {
          ...initialState,
          isFetching: false,
          data: action.data,
          noRadio:!hasRadio,
          noClients:!hasClients,
          noWLAN:!hasWLAN
        };
        case aTypes.LOAD_SWITCH_FAILURE:
          return {
            ...initialState,
            isFetching: false,
            error: action.data
          };
        default:
          return state;
      }
    }
    

    4. Action

    Right part(actions) of mapDispatchToProps

    看看Actions在哪里注册? manageAction.device

    import manageAction from '../../actions';
    
    function mapDispatchToProps(dispatch){
      return {
            actions: bindActionCreators(manageAction.device, dispatch)
        };
    }
    

    =>manageAction

    import * as deviceAction from './device';
    export default {
      device: deviceAction
    };
    

    => device.js(actions+dispatch)

    Action就是修改数据和状态,dispatch到reducer去处理,reducer返回state给Container去刷新Component或响应事件。

    export function retrieveSwithDetail(switch_id) {
      return async (dispatch, getState) => {
        try {
          dispatch({
            type: aTypes.LOAD_SWITCH //Loading...
          }); 
          // populate dynamic data from tsnData
          data["temperature"] = 34;
          dispatch({
            type: aTypes.LOAD_SWITCH_SUCCESS,//Load succeed
            data: data
          });
        } catch (error) {
          dispatch({
            type: aTypes.LOAD_SWITCH_FAILURE,//Load failed
            data: error
          });
        }
      };
    }
    

    =>Reducer(switchDetail.js) handle the dispatch (type+data)

    export default function switchDetail(state = initialState, action){
      switch (action.type) {
        case aTypes.LOAD_SWITCH:
          return {
            ...initialState,
            isFetching: true,//Changed the state and make component updated
            data: {}
          };
        case aTypes.LOAD_SWITCH_SUCCESS:
        
    

    Summary

    • Reducer provides state and actions to store data and make component update
    • Action returns state with type and data.
    • Reducer handles actions and return state(props),state changes make component update.
    • Container providers props to component and connect props with reducer state.
    • Define Action types as constants.

    Reference

    相关文章

      网友评论

          本文标题:React Native+Redux设计模式

          本文链接:https://www.haomeiwen.com/subject/rqwsgftx.html