54

React Native 添加 Redux 支持

 4 years ago
source link: https://www.tuicool.com/articles/myeuUbF
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

0x1 前言

之前写的项目都是人家编写好的脚手架,里面包含项目所需的环境文件,但由于有些东西用不到打包增加软件体积,所以自己从头搭建个环境。是基于 Native Base + react-navigation + ReduxReact Native 脚手架,现在项目环境如下:

{
  "name": "app",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "native-base": "^2.13.4",
    "react": "16.8.6",
    "react-native": "0.60.5",
    "react-native-gesture-handler": "^1.3.0",
    "react-native-keyboard-aware-scroll-view": "^0.9.1",
    "react-native-reanimated": "^1.2.0",
    "react-navigation": "^3.11.1"
  },
  "devDependencies": {
    "@babel/core": "^7.5.5",
    "@babel/runtime": "^7.5.5",
    "@react-native-community/eslint-config": "^0.0.5",
    "babel-eslint": "7.2.3",
    "babel-jest": "^24.8.0",
    "eslint": "4.4.1",
    "eslint-plugin-flowtype": "2.35.0",
    "eslint-plugin-import": "2.7.0",
    "eslint-plugin-jsx-a11y": "6.0.2",
    "eslint-plugin-prettier": "2.1.2",
    "eslint-plugin-react": "7.1.0",
    "eslint-plugin-react-native": "3.0.1",
    "jest": "^24.8.0",
    "metro-react-native-babel-preset": "^0.56.0",
    "prettier": "1.5.3",
    "react-test-renderer": "16.8.6"
  },
  "jest": {
    "preset": "react-native"
  }
}

0x2 添加 Redux 支持

这里大概讲解下安装类库支持:

yarn add yarn add react-navigation react-native-gesture-handler react-native-reanimated native-base

链接字体库资源:

react-native link

react-navigationAndroid 环境额外添加代码支持,具体情况文档: MainActivity.java

react-navigationreact-native 版本大于 0.60 的时候不需要执行 react-native link 链接。

由于项目需要状态管理支持,故添加 Redux 状态管理类库支持,在 React Native 环境下和 React 项目一样:

yarn add redux react-redux redux-logger

redux-logger 是监控状态数据流日志,可以在控制台输出状态值的信息。

由于项目基本环境是 Native Base 环境,这里怎么安装它就不再描述了,故在基础项目下添加项目支持 Redux 即可。打开 ./src/App.js 添加 Redux 能力支持:

import {Root} from "native-base";
import {createStackNavigator, createAppContainer} from "react-navigation";
import {applyMiddleware, createStore} from "redux";
import {Provider} from "react-redux";
import React from "react";
import logger from "redux-logger";
import allReducers from "./store";
import reduxDemo from "./screens/reduxDemo";
 
const store = createStore(
  allReducers,
  applyMiddleware(logger)
); // 创建 Store
 
const AppNavigator = createStackNavigator(
  {
    ReduxDemo: {screen: reduxDemo},
  },
  {
    initialRouteName: "ReduxDemo", // 路由入口
    headerMode: "none", // 由于 react-navigation 默认导航栏自定义效果很差,故隐藏
  },
);
 
const AppContainer = createAppContainer(AppNavigator);
 
export default () => (
  <Provider store={store}>
    <Root>
      <AppContainer/>
    </Root>
  </Provider>
);

创建状态触发事件业务集 ./store/reducers/counter.js

let count = 0;
export default function (state = count, action) {
  switch (action.type) {
    case "Increment":
      count++;
      break;
    case "Decrement":
      count--;
      break;
  }
  return count;
}

这里是根据触时不同条件要执行的业务,例如数字的增加和减少。假如项目下有很多触发业务集合,我们需要把他们归纳一起,并且方便获取状态值获取,新建 ./src/store/index.js

import {combineReducers} from "redux";
import countReducer from "./reducers/counter";
 
const allReducers = combineReducers({
  count: countReducer,
});
export default allReducers;

然后需要有个动作器来触发上面的业务,新建 ./src/store/actions/counter.js

export function increment() {
  return {
    type: "Increment"
  };
}
 
export function decrement() {
  return {
    type: "Decrement"
  };
}

如果需要改动状态值只能从上面的函数进行触发,这是唯一入口。

下面就编写页面进行测试,新建 ./src/screens/reduxDemo/index.js

import React, {Component} from "react";
import {Container, Content, Text, Card, Header, Body, Button, Title, CardItem} from "native-base";
import {increment, decrement} from "../../store/actions/counter";
import {bindActionCreators} from "redux";
import {connect} from "react-redux";
 
class Counter extends Component {
  render() {
    console.log(this.props.count);
    return (
      <Container>
        <Header>
          <Body>
            <Title>Redux 计数器</Title>
          </Body>
        </Header>
        <Content padder>
          <Card>
            <CardItem>
              <Text>
                {this.props.count}
              </Text>
            </CardItem>
          </Card>
          <Text/>
          <Button block onPress={() => this.props.increment()}>
            <Text>增加</Text>
          </Button>
          <Text/>
          <Button block onPress={() => this.props.decrement()}>
            <Text>减少</Text>
          </Button>
        </Content>
      </Container>
    );
  }
}
 
function mapStateToProps(state) {
  return {
    count: state.count // 这里等效于 prop.state 不过redux1帮你封装好的
  };
}
 
function matchDispatchToProps(dispatch) {
  return bindActionCreators({increment: increment, decrement: decrement}, dispatch); // 绑定动作事件
}
 
export default connect(mapStateToProps, matchDispatchToProps)(Counter); // 连接Redux

总结

代码参考: RN-Demo


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK