React-Native: redux、react-redux

中文文档

 Redux 中文文档 · Redux

安装

npm install redux react-redux

使用

1、在 src 目录下新建文件 redux/store.js 和 redux/reducer.js 。

2、在 src 目录下新建文件 redux/actions/ActionTypes.js 。

3、在 src 目录下新建文件 redux/reducers/system.js 和 redux/reducers/userInfo.js。(命名随便,你也可以创建其他的 reducers.js 文件)

4、ActionTypes.js

存放ActionTypes常量,避免写在每个reducers里面导致类型重复。

正确格式为 export const CHANGE_USERINFO = 'CHANGE_USERINFO';

为了方便阅读,我把后面改为小写,因为大写常量命名在我看来会造成阅读负担。

// 更新 userInfo
export const CHANGE_USERINFO = 'change_userInfo';

// 重置 userInfo
export const RESET_USERINFO = 'reset_userInfo';

// 更新 system 信息
export const CHANGE_SYSTEM = 'change_system';

// 重置 system 信息
export const RESET_SYSTEM = 'reset_system';

5、system.js

import {CHANGE_SYSTEM, RESET_SYSTEM} from '../actions/ActionTypes';

// 定义状态的默认值
let initialState = {
  appName: 'RNDemoApp',
  weatherList: [],
};

export const system = (
  prevState = {
    ...initialState,
  },
  action,
) => {
  switch (action.type) {
    case CHANGE_SYSTEM:
      return {...prevState, ...action.payload};

    case RESET_SYSTEM:
      return initialState;

    default:
      return prevState;
  }
};

6、 userInfo.js

import {CHANGE_USERINFO, RESET_USERINFO} from '../actions/ActionTypes';

// 定义状态的默认值
let initialState = {
  name: 'baidu',
};

export const userInfo = (
  prevState = {
    ...initialState,
  },
  action,
) => {
  switch (action.type) {
    case CHANGE_USERINFO:
      return action.payload;

    case RESET_USERINFO:
      return initialState;

    default:
      return prevState;
  }
};

7、 reducer.js

import {combineReducers} from 'redux';
import {system} from './reducers/system';
import {userInfo} from './reducers/userInfo';

const reducer = combineReducers({
  system,
  userInfo,
});

export default reducer;

8、 store.js

import {legacy_createStore as createStore} from 'redux';
import reducer from './reducer';

const store = createStore(reducer);

export default store;

9、在项目入口文件,我这里是App.js

10、页面的调用与更新

import React from 'react';
import {StyleSheet, View, Text} from 'react-native';
import {connect} from 'react-redux';
import {
  commonColors,
  commonSize,
  commonStyle,
} from 'src/assets/css/commonStyle';
import {SafeAreaView} from 'react-native-safe-area-context';
import {CtBtn, CustomNavbar, HeightSpacer} from 'src/components';
import {
  CHANGE_SYSTEM,
  CHANGE_USERINFO,
  RESET_SYSTEM,
  RESET_USERINFO,
} from 'src/redux/actions/ActionTypes';

const ReduxData = props => {
  return (
    <SafeAreaView style={[commonStyle.container, commonStyle.bgFFF]}>
      <CustomNavbar
        headerTitle={'redux数据'}
        borderColor={commonColors.borderColorLighter}
      />
      <HeightSpacer />
      <Text>userInfo.name: {props.userInfo.name}</Text>
      <HeightSpacer />
      <Text>system.appName: {props.system.appName}</Text>
      {props.system.version && (
        <>
          <HeightSpacer />
          <Text>system.appName: {props.system.version}</Text>
        </>
      )}
      <HeightSpacer />
      <CtBtn
        btnText={'更改 userInfo.name'}
        width={commonSize.width}
        onPress={() => {
          props.changeUserInfo({
            name: 'chrome',
          });
        }}
      />
      <HeightSpacer />
      <CtBtn
        btnText={'更改 system.appName'}
        width={commonSize.width}
        onPress={() => {
          props.changeSystem({
            appName: 'superApp',
          });
        }}
      />
      <HeightSpacer />
      <CtBtn
        btnText={'新增 system.version'}
        width={commonSize.width}
        onPress={() => {
          props.changeSystem({
            version: '0.0.1',
          });
        }}
      />
      <HeightSpacer />
      <CtBtn
        btnText={'重置'}
        width={commonSize.width}
        onPress={() => {
          props.resetUserInfo();
          props.resetSystem();
        }}
      />
    </SafeAreaView>
  );
};
// 映射 Redux store state 数据到组件中
const mapStateToProps = state => {
  return {
    userInfo: state.userInfo,
    system: state.system,
  };
};
// 组件分发 action
const mapDispatchToProps = {
  changeUserInfo(data) {
    return {
      type: CHANGE_USERINFO,
      payload: data,
    };
  },
  changeSystem(data) {
    return {
      type: CHANGE_SYSTEM,
      payload: data,
    };
  },
  resetUserInfo(data) {
    return {
      type: RESET_USERINFO,
    };
  },
  resetSystem(data) {
    return {
      type: RESET_SYSTEM,
    };
  },
};
export default connect(mapStateToProps, mapDispatchToProps)(ReduxData);

const styles = StyleSheet.create({});

11、页面展示

12、在没有中间件的情况下,异步获取数据后,分发 dispatch action

获取某地区今明后天气数据

https://devapi.qweather.com/v7/weather/3d?location=116.41,39.92&key=ab016705d280420b8d72f5c6892901dc

网上找的一个接口。。。

 试想一下,当接口数据需要放到 store 储存起来的时候,说明该数据在其他页面、组件中也会用到,但是以上面这种方式开发,就不得不把接口请求的部分,复制到其他页面,后续接口有改动就要改很多地方,麻烦且烦琐。

中间件的使用 - redux-thunk

redux只支持同步的action,需要使用一些中间件让 action 返回一个函数,我们在函数中实现异步的操作

安装

npm install redux-thunk

使用

1、改造 store.js 

applyMiddleware 可支持多种中间件

import {legacy_createStore as createStore, applyMiddleware} from 'redux';
import reduxThunk from 'redux-thunk';
import reducer from './reducer';

const store = createStore(reducer, applyMiddleware(reduxThunk));

export default store;

2、在 src 目录下新建文件 redux/actionCreator/getWeatherAction.js 。

3、actionCreator/getWeatherAction.js

import {getWeatherApi} from 'src/api/api';
import {CHANGE_SYSTEM} from '../actions/ActionTypes';

export const getWeatherData = () => {
  return async dispatch => {
    console.log(dispatch);
    let resApi = await getWeatherApi({
      location: '116.41,39.92',
      key: 'ab016705d280420b8d72f5c6892901dc',
    });
    dispatch({
      type: CHANGE_SYSTEM,
      payload: {
        weatherList: resApi.daily,
      },
    });
  };
};

4、 页面的调用与更新

 把异步请求放在 dispatch action 时,此时的api请求也有共享的状态。

getWeatherData方法还可以传递参数,在actions/index.js处理参数进行业务的处理逻辑。

中间件的使用 - redux-promise

阮一峰老师在《Redux 入门教程(二):中间件与异步操作》写到:

既然 Action Creator 可以返回函数,当然也可以返回一个 Promise 对象,这就是 redux-promise 中间件。redux-promise 中间件就是 redux-thunk 与 promise 的结合。

安装

npm install redux-promise

1、修改 store.js 

import {legacy_createStore as createStore, applyMiddleware} from 'redux';
import reduxThunk from 'redux-thunk';
import reduxPromise from 'redux-promise';
import reducer from './reducer';

const store = createStore(reducer, applyMiddleware(reduxThunk, reduxPromise));

export default store;

2、 修改 actionCreator/getWeatherAction.js

import {getWeatherApi} from 'src/api/api';
import {CHANGE_SYSTEM} from '../actions/ActionTypes';

// redux-thunk 写法
// export const getWeatherData = () => {
//   return async dispatch => {
//     console.log(dispatch);
//     let resApi = await getWeatherApi({
//       location: '116.41,39.92',
//       key: 'ab016705d280420b8d72f5c6892901dc',
//     });
//     dispatch({
//       type: CHANGE_SYSTEM,
//       payload: {
//         weatherList: resApi.daily,
//       },
//     });
//   };
// };

// redux-promise 写法
export const getWeatherData = async () => {
  return await getWeatherApi({
    location: '116.41,39.92',
    key: 'ab016705d280420b8d72f5c6892901dc',
  }).then(res => {
    return {
      type: CHANGE_SYSTEM,
      payload: {
        weatherList: res.daily,
      },
    };
  });
};

中间件的使用 - redux-saga

目前觉得 redux-saga 比上述两种麻烦,就没有用,但是很多人在推荐 redux-saga。

redux-promise 没有更新了

redux-thunk 每周的下载量比 redux-saga 大,所有暂时先不使用redux-saga了。

中间件的使用 - redux-logger

redux-logger - npm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
react-native-redux-router是一个用于在React Native应用中管理路由和状态的库。它结合了React NativeReduxReact Navigation,提供了一种方便的方式来处理应用程序的导航和状态管理。 下面是一个简单的示例,演示了如何在React Native应用中使用react-native-redux-router: 1. 首先,安装所需的依赖项。在终端中运行以下命令: ```shell npm install react-native react-redux redux react-navigation react-native-router-flux --save ``` 2. 创建一个Redux store,并将其与React Native应用程序的根组件连接起来。在App.js文件中,添加以下代码: ```javascript import React from 'react'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; import rootReducer from './reducers'; import AppNavigator from './navigation/AppNavigator'; const store = createStore(rootReducer); export default function App() { return ( <Provider store={store}> <AppNavigator /> </Provider> ); } ``` 3. 创建一个导航器组件,并定义应用程序的导航结构。在navigation/AppNavigator.js文件中,添加以下代码: ```javascript import { createAppContainer } from 'react-navigation'; import { createStackNavigator } from 'react-navigation-stack'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { Actions } from 'react-native-router-flux'; import HomeScreen from '../screens/HomeScreen'; import DetailsScreen from '../screens/DetailsScreen'; const MainNavigator = createStackNavigator({ Home: { screen: HomeScreen }, Details: { screen: DetailsScreen }, }); const AppNavigator = createAppContainer(MainNavigator); const mapStateToProps = state => ({ // 将Redux状态映射到导航器组件的props中 }); const mapDispatchToProps = dispatch => bindActionCreators(Actions, dispatch); export default connect(mapStateToProps, mapDispatchToProps)(AppNavigator); ``` 4. 创建屏幕组件,并在其中使用导航和Redux状态。在screens/HomeScreen.js文件中,添加以下代码: ```javascript import React from 'react'; import { View, Text, Button } from 'react-native'; import { Actions } from 'react-native-router-flux'; const HomeScreen = () => { return ( <View> <Text>Welcome to the Home Screen!</Text> <Button title="Go to Details" onPress={() => Actions.details()} /> </View> ); } export default HomeScreen; ``` 5. 创建其他屏幕组件,并在其中使用导航和Redux状态。在screens/DetailsScreen.js文件中,添加以下代码: ```javascript import React from 'react'; import { View, Text, Button } from 'react-native'; import { Actions } from 'react-native-router-flux'; const DetailsScreen = () => { return ( <View> <Text>Welcome to the Details Screen!</Text> <Button title="Go back" onPress={() => Actions.pop()} /> </View> ); } export default DetailsScreen; ``` 这是一个简单的示例,演示了如何在React Native应用中使用react-native-redux-router来管理路由和状态。你可以根据自己的需求进行扩展和定制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值