Skip to content

React-Native 搭建开发环境

安装 RN 脚手架和 yarn:npm i react-native-cli yarn -g

创建项目:react-native init demo

如果 init 太慢,可以使用淘宝的镜像

bash
// 查看下载源
yarn config get registry
// 更换为淘宝源
yarn config set registry https://registry.npm.taobao.org
// 查看下载源
yarn config get registry
// 更换为淘宝源
yarn config set registry https://registry.npm.taobao.org

启动服务器:react-native start

等一段时间,用浏览器访问http://localhost:8081/index.android.bundle?platform=android可以访问,即启动完成,启动之后不能关闭;

安装 app:react-native run-android

在输入此命令前,要先打开模拟器,或连接真机,第一次启动非常慢,需要下载 gradle,也可以手动下载 gradle 安装。

加速 gradle

找到build.gradle修改成下面这样

jsx
buildscript {
    repositories {
        maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
    }
}
buildscript {
    repositories {
        maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
    }
}

安卓必须 5.0 以上,支持adb reverse命令

配置 eslint

bash
npm install eslint babel-eslint eslint-plugin-react --save-dev
npm install eslint babel-eslint eslint-plugin-react --save-dev

这里根据自己喜欢的规则来配置

json
{
  "env": {
    "browser": true,
    "commonjs": true,
    "es6": true,
    "node": true
  },
  "parser": "babel-eslint",
  "extends": ["eslint:recommended", "plugin:react/recommended"],
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "sourceType": "module"
  },
  "rules": {
    "react/prop-types": "off"
  }
}
{
  "env": {
    "browser": true,
    "commonjs": true,
    "es6": true,
    "node": true
  },
  "parser": "babel-eslint",
  "extends": ["eslint:recommended", "plugin:react/recommended"],
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "sourceType": "module"
  },
  "rules": {
    "react/prop-types": "off"
  }
}

React-Navigation 与 redux 的整合

https://reactnavigation.org/docs/guides/redux

首先安装npm i react-navigation

配置路由信息

jsx
import { StackNavigator, addNavigationHelpers, NavigationActions } from "react-navigation";

const AppRouteConfigs = {
  Main: { screen: MainView },
  Profile: { screen: ProfileView },
};
const AppNavigator = StackNavigator(AppRouteConfigs, {
  initialRouteName: "Main",
  headerMode: "none",
});
import { StackNavigator, addNavigationHelpers, NavigationActions } from "react-navigation";

const AppRouteConfigs = {
  Main: { screen: MainView },
  Profile: { screen: ProfileView },
};
const AppNavigator = StackNavigator(AppRouteConfigs, {
  initialRouteName: "Main",
  headerMode: "none",
});

编写路由的 reducer

jsx
const initialState = AppNavigator.router.getStateForAction(AppNavigator.router.getActionForPathAndParams("Main"));
const navReducer = (state = initialState, action) => {
  const nextState = AppNavigator.router.getStateForAction(action, state);
  return nextState || state;
};
const appReducer = combineReducers({
  nav: navReducer,
  app: reducer,
});
const initialState = AppNavigator.router.getStateForAction(AppNavigator.router.getActionForPathAndParams("Main"));
const navReducer = (state = initialState, action) => {
  const nextState = AppNavigator.router.getStateForAction(action, state);
  return nextState || state;
};
const appReducer = combineReducers({
  nav: navReducer,
  app: reducer,
});

编写路由的根组件

jsx
class App extends Component {
  componentDidMount() {
    BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
  }
  componentWillUnmount() {
    BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
  }
  onBackPress = () => {
    const { dispatch, nav } = this.props;
    if (nav.index === 0) {
      return false;
    }
    dispatch(NavigationActions.back());
    return true;
  };
  render() {
    return (
      // 这里将两个工具属性注入到路由中
      <AppNavigator
        navigation={addNavigationHelpers({
          dispatch: this.props.dispatch,
          state: this.props.nav,
        })}
      />
    );
  }
}
class App extends Component {
  componentDidMount() {
    BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
  }
  componentWillUnmount() {
    BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
  }
  onBackPress = () => {
    const { dispatch, nav } = this.props;
    if (nav.index === 0) {
      return false;
    }
    dispatch(NavigationActions.back());
    return true;
  };
  render() {
    return (
      // 这里将两个工具属性注入到路由中
      <AppNavigator
        navigation={addNavigationHelpers({
          dispatch: this.props.dispatch,
          state: this.props.nav,
        })}
      />
    );
  }
}

生成带有 redux 状态的根组件

jsx
const mapStateToProps = (state) => ({
  nav: state.nav,
});
const AppWithNavigationState = connect(mapStateToProps)(App);
const store = createStore(appReducer);

class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <AppWithNavigationState />
      </Provider>
    );
  }
}
const mapStateToProps = (state) => ({
  nav: state.nav,
});
const AppWithNavigationState = connect(mapStateToProps)(App);
const store = createStore(appReducer);

class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <AppWithNavigationState />
      </Provider>
    );
  }
}

用 adb 发送 menu 事件打开 dev 菜单

bash
adb shell input keyevent 82
adb shell input keyevent 82

最后编辑时间:

Version 4.0 (framework-1.0.0-rc.20)