reactNative开发移动端
用reactNative(VsCode编译器)开发移动端界面,Android开发后端接口(Android Studio编译器)。
RN官网(搭建环境于API手册):https://reactnative.cn/docs/environment-setup
reactNative界面开发
背景: reactNative提供组件,或者使用第三方库提供的组件,数据(包含规则校验)由 yup、formik提供,除启动界面:login,register,splash等账户登录后,一般使用导航栏(@react-navigation/drawer、‘npm install react-native-gesture-handler react-native-reanimated’)包含抽屉(Drawer Navigator)、tab切换(Bottom Tabs Navigator)进行路由导航(一般适用于简单页面切换),详情API请看https://reactnavigation.org/docs/drawer-navigator
RN前端开发技巧:
1\写了一系列组件或者网上推荐好用的组件放到component文件夹下,每个组件用export default xxx;【其他界面也可以加default】,定义index.ts放在component文件夹下,index.ts中写各个组件的export {default as Header} from "./Header";
,集中一起导出,使用时在界面中引入import { theme, Box, Text, Header, LableValueInput, Error, Loading, ConfirmModal, } from '~/component';
例如: index.ts 其他界面也可以借鉴index.ts的思路
export {default as Container} from "./Container";
export {default as Footer} from "./Footer";
export {default as Button} from "./Button";
export {default as theme,Text,Box} from "./Theme";
export {default as RoundedIcon} from "./RoundedIcon";
export {default as Header} from "./Header";
export {default as TextInput, } from "./Form/TextInput";
export {default as TextInputRightBtn} from "./Form/TextInputRightBtn";
export {default as LableValueInput} from "./Form/LableValueInput";
export {default as CusCheckbox} from "./Form/CusCheckbox";
export { AuthContext} from "./context/AuthContext";
export { UserContext} from "./context/UserContext";
export { default as Loading} from "./Loading";
export { default as Error} from "./Error";
// export { default as IDCard0} from "./IDCard0";
// export { default as Tabs} from "./Tabs";
// export { default as UpgradeAppModel} from "./UpgradeAppModel";
export { default as ConfirmModal} from "./ConfirmModal";
前端init.bat文件部分组件
rem 界面基础组件
yarn add react-native
yarn add @ant-design/react-native
rem 界面数据(formik)与表单验证(Yup验证规则)
npm install yup
npm install formik
rem 统一样式模板
yarn add @shopify/restyle
rem 菜单导航栏
yarn add @react-navigation/drawer
yarn add @react-navigation/native
yarn add react-native-gesture-handler react-native-reanimated
rem 其他组件(第三方)
yarn add react-native-keyboard-aware-scroll-view
npm i uuid-random
rem 底部滑出的下拉选择矿(其他方向也可)
yarn add react-native-picker
第三方组件解析
1、定义theme主题@shopify/restyle;菜单导航@react-navigation/drawer、@react-navigation/native;
(1)实现修改少量参数切换主题api文档地址:https://github.com/Shopify/restyle
(2)navigation相关文档,可配合context使用上下文和hook进行数据传递和接口调用,刺激界面刷新(需要搜索案例)
https://reactnavigation.org/docs/drawer-navigator
使用:
在navigation界面或者app.js中定义<ThemeProvider theme={theme}></ThemeProvider>
,颜色可取 theme.themecolors.primary等等。
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';
import {
ThemeProvider,
createBox,
createText,
createRestyleComponent,
createVariant,
VariantProps,
} from '@shopify/restyle';
import theme from '~/component/Theme';
const Drawer = createDrawerNavigator();
export default function XXXDrawerNavigator() {
return (
<ThemeProvider theme={theme}>
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home" otherProps...>
<Drawer.Screen name="Home" component={HomeScreen} options={{
title: 'XXX配置',
otherProps...,
}}></Drawer.Screen>
<Drawer.Screen name="Notifications" component={NotificationsScreen} options={{
title: 'XXX分析',
drawerIcon: ({focused, size}) => (
<Ionicons
name="checkmark-circle-outline"
size={size}
color={focused ? '#7cc' : '#ccc'}
/>
),
}}></Drawer.Screen>
</Drawer.Navigator>
</NavigationContainer>
</ThemeProvider>
}
RN问题记录
1、使用theme.js写的公共组件报错(funcMap[props] undefined)
原因:import @shopify/restyle没有定义 <ThemeProvider theme={theme}></ThemeProvider>
解决方式:在根页面定义<ThemeProvider theme={theme}><ThemeProvider>
,或单独使用的页面也要加这个。
案例如下
描述: 导航页TCPZDrawerNavigator.js引入ThemeProvider标签;使用页面YDLXDTList.js应用组件LableValueInput;定义公共组件LableValueInput.js(使用了@shopify/restyle、theme)
使用公共组件和统一样式:代码只包含使用公用组件LableValueInput用法,样式部分可能会报错,需要修改
import React, { useState } from 'react';
import * as Yup from 'yup';
import { Formik, useFormik, useField } from 'formik';
// 原生接口
import { YDLXDTService, RunActivity } from '~/native/nativeModules';
import {Container,Button,Box,CusCheckbox,Header,UserContext,LableValueInput,ConfirmModal, Error} from '~/components'
//模板校验规则
const ydlxdtSchema = Yup.object().shape({
mc: Yup.string()
// 只能输入数字、字母、汉字
.matches( /^[\da-zA-Z\u4E00-\u9FA5]+$/u,'图层名称存在违规字符,请重新输入!')
.required('图层名称必填'),
lx: Yup.string()
.matches( /^[\da-zA-Z_\u4E00-\u9FA5\-.]+$/u,'矢量数据类型存在违规字符,请重新输入!'),
address: Yup.string()
.matches( /^[\da-zA-Z_\u4E00-\u9FA5\-.]+$/u,'详细地址存在违规字符,请重新输入!')
.required('详细地址必填'),
dh: Yup.string()
.matches( /^[\da-zA-Z_\u4E00-\u9FA5\-.]+$/u,'地号存在违规字符,请重新输入!'),
zValue: Yup.string()
.matches( /^[\da-zA-Z\u4E00-\u9FA5]+$/u,'证书编号的字存在违规字符,请重新输入!')
.required('证书编号的字必填'),
hValue: Yup.string()
.matches( /^[\da-zA-Z\u4E00-\u9FA5]+$/u,'证书编号的号存在违规字符,请重新输入!')
.required('证书编号的号必填'),
syqmj: Yup.number(),
page: Yup.number().min(1),
});
export function YDLXDTList() {
// 这里有其他定义的let [ydlxdt, setYdlxdt] = React.useState({});
const { handleChange, handleBlur, handleSubmit, errors,touched,values,setFieldValue,setValues }=
useFormik({validationSchema:ydlxdtSchema,
initialValues: {
tcid: ydlxdt?.tcid,
xh: ydlxdt && ydlxdt.xh ? ydlxdt.xh : "",
mc:ydlxdt && ydlxdt.mc?ydlxdt.mc:"",
lx: ydlxdt && ydlxdt.lx?ydlxdt.lx:"",
fz:ydlxdt && ydlxdt.fz?ydlxdt.fz:"",
fzxh:ydlxdt && ydlxdt.fzxh ?ydlxdt.fzxh :'',
tbzt:ydlxdt && ydlxdt.tbzt?ydlxdt.tbzt:"是",
tbsj:ydlxdt && ydlxdt.tbsj?ydlxdt.tbsj:"",
sfdt:ydlxdt && ydlxdt.sfdt? ydlxdt.sfdt:"",
sfnbcc :ydlxdt && ydlxdt.sfnbcc? ydlxdt.sfnbcc:"",
minScale: ydlxdt && ydlxdt.minScale?ydlxdt.minScale:"",
maxScale: ydlxdt && ydlxdt.maxScale?ydlxdt.maxScale:"",
sfjz: ydlxdt && ydlxdt.sfjz?ydlxdt.sfjz:"",
ipaddress:ydlxdt?.ipaddress,
sfquery: ydlxdt?.sfquery,
sfzyfx: ydlxdt?.sfzyfx
},
onSubmit: values => {
console.log('onsubmit');
debugger;
console.log(values);
// 处理 每个字段是否包含敏感词,并直接替换为空
handleSensitiveWord(values);
dataHandle.qzxx_save(userData.token,values,saveQzxxCallBack,refreshQZXXState);
},
}
);
return (
<SafeAreaView style={styles.container}>
<Loading loading={loading}></Loading>
<LableValueInput
labelName="权利人"
placeholder="请输入权利人"
value={values.qlrxm}
onChangeText={handleChange('qlrxm')}
onBlur={handleBlur('qlrxm')}
error={errors.qlrxm}
touched={touched.qlrxm}
borderBottomColor="text2"
labelTextCss={styles.labelTextCss}
style={styles.valueText}
/>
</SafeAreaView>
)
}
定义LableValueInput组件
import React, { useState,forwardRef } from "react";
import {View,StyleSheet,TextInput } from "react-native";
import Icon from 'react-native-vector-icons/Ionicons';
import theme,{ Box,Text} from "../Theme";
import RoundedIcon from "../RoundedIcon";
const SIZE= theme.borderRadii.m*2;
const LableValueInput = forwardRef(({labelName,touched,error,borderBottomColor,labelTextCss,...props},ref)=>{
debugger;
const reColor = !touched ? "text2" : error ? "danger" : "primary";
const color=theme.colors[reColor];
return (
<Box flexDirection="row"
alignItems = "center"
borderBottomWidth={StyleSheet.hairlineWidth}
{...{borderBottomColor}}
>
<Text style={labelTextCss}>{labelName}</Text>
<TextInput underlineColorAndroid="transparent" flex={1}
placeholderTextColor={color}
{...{ref}}
{...props}/>
{(touched) &&
(
<RoundedIcon
name={!error?"ios-checkmark":"ios-close"}
size={SIZE}
backgroundColor={!error?"primary":"danger"}
color="white"
/>
)
}
</Box>
)
})
export default LableValueInput;
导航页面TCPZDrawerNavigator.js引用theme、@shopify/restyle
import * as React from 'react';
import { Button, View } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';
import HomeScreen from '~/module/screens/tcpz/HomeScreen';
import LxdtScreen from '~/module/screens/xmhc/YDLXDTList';
import Ionicons from 'react-native-vector-icons/Ionicons';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import {GEONavigator} from '~/module/navigators/GEONavigator';
import {YDLXDTNavigator} from '~/module/navigators/YDLXDTNavigator';
import CustomerDrawer from '~/module/navigators/CustomerDrawer';
import {
ThemeProvider,
createBox,
createText,
createRestyleComponent,
createVariant,
VariantProps,
} from '@shopify/restyle';
import theme from '~/component/Theme';
const Drawer = createDrawerNavigator();
const focused='#7cc';
const size = 22;
// 图层配置菜单
export default function TCPZDrawerNavigator() {
return (
<ThemeProvider theme={theme}>
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home"
screenOptions={{headerShown:true,drawerActiveBackgroundColor:'#7cc',
drawerActiveTintColor:'#fff', drawerInactiveTintColor:'#333', drawerLabelStyle:{marginLeft:-25,fontFamily:'Roboto-Medium',fontSize:15}}}
drawerContent={props =><CustomerDrawer {...props} />}>
<Drawer.Screen name="Home" component={HomeScreen} options={{
title: '图层配置',
drawerIcon: ({focused, size}) => (
<Ionicons
name="globe-outline"
size={size}
color={focused ? '#7cc' : '#ccc'}
/>
),
}}></Drawer.Screen>
<Drawer.Screen name="YDLXDTNavigator" component={YDLXDTNavigator} options={{
title: '离线地图',
drawerIcon: ({focused, size}) => (
<MaterialIcons
name="workspaces-outline"
size={size}
color={focused ? '#7cc' : '#ccc'}
/>
),
}}/>
<Drawer.Screen name="GEONavigator" component={GEONavigator} options={{
title: 'Geo',
drawerIcon: ({focused, size}) => (
<MaterialIcons
name="workspaces-outline"
size={size}
color={focused ? '#7cc' : '#ccc'}
/>
),
}}/>
</Drawer.Navigator>
</NavigationContainer>
</ThemeProvider>
);
}
2、安装react-native-reanimated后运行yarn android启动程序报错
解决方案:在本地 babel.config.js添加Reanimated’s babel plugin
module.exports = {
presets: [
...
],
plugins: [
...
'react-native-reanimated/plugin',
],
};
在添加react-native-reanimated/plugin
后,你可能会遇到"Reanimated 2 failed to create a worklet" error,需要清除应用缓存,可以执行命令yarn start --reset-cache
或npm start -- --reset-cache
或expo start -c
3、安装了@react-native-community/picker后又yarn add @react-native-picker/picker报错
报错信息: Type com.reactnativecommunity.picker.BuildConfig is defined multiple times
原因:@react-native-community/picker
与 @react-native-picker/picker
是相同的包,安装后在package.json中都被依赖,造成冲突[Picker]
解决方式:删除@react-native-community/picker
库,删除后若报错,请清除缓存npm start --clean-cache文章来源:https://www.toymoban.com/news/detail-642866.html
npm uninstall -D package-name 或 npm uninstall --save-dev package-name
例如:npm uninstall --save @react-native-community/picker // 笔者使用的该行命令,上两种也可
或者其他方式:文章来源地址https://www.toymoban.com/news/detail-642866.html
1、react-native unlink <lib name> // 平台不要链接
2、react-native uninstall <lib name> // node modules 和 package.json中dependencies 卸载包
3、若执行--save命令后package.json没有清除包的声明,请手动移除 package.json中的 包名
到了这里,关于【reactNative混合安卓开发~使用问题持续更】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!