美文网首页
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