最近使用react-native
参与开发了个应用,记录下其中踩的一些坑。本人使用的是mac电脑进行开发,本文仅对此平台进行记录📝
下载不了xcode
升级自己的mac的系统到最新版本,之后在mac的应用市场中下载xcode。
请保持网络的顺畅,升级系统和下载安装xcode
比较耗时,需耐心等待啦~
ran "xcodebuild" command, error code for 65
跑起来的时候可能会出现这样的错误:
error Failed to build iOS project. We ran "xcodebuild" command but it exited with error code 65. To debug build logs further, consider building your app with Xcode.app, by
可以参考下面的步骤解决:
- 用xcode当前当前项目,如
File -> Open -> demo_native -> ios
- 选择
File -> Project Setting -> Advanced -> Custom -> Relative to workspace
- rm -rf node_modules
- killall -9 com.apple.CoreSimulator.CoreSimulatorService
- sudo react-native run-ios
react-native run-ios
后没反应
在完成了相关的下载之后,运行react-native项目之后过两三分钟还是没有反应,请确保你的网络良好并重新运行,等待上一段时间。
首次跑应用耗时比较长,第二次跑的话就很快了~
出现Entry, ":CFBundleIdentifier", Does Not Exist
错误
在执行react-native run-ios
后出现Entry, ":CFBundleIdentifier", Does Not Exist
,可以通过更改文件的设置来解决,xcode打开文件目录后,File -> Project Setting -> Advanced -> Custom -> Relative to workspace
。如果还是不行,请使用好点的工具(比如使用SS,而不是蓝灯)。
最主要的还是保持网络的良好,不然相关依赖下载会失败的
实现页面的热加载
在项目启动之后,mac上的模拟器已经开启了,但是修改保存ide上的代码后,模拟器并不能够实现热加载。这个时候应该开启模拟器的项目热加载功能。做法如下:
模拟器中进入正在执行的项目,然后在mac上按住command + d
就可以调出对话框,选择Enable Live Reload
就可以了。
关联浏览器调试
运行项目之后,可以在浏览器内对应用的js进行调试。调试操作:
- 运行项目后在浏览器上打开
http://localhost:8081/debugger-ui/
- 在启动的项目中开启远程js debugger。
command+d -> Debug JS Remotely
⚠️【开启远程调试会拖慢app的运行速度,有需要的时候再开启】
基础要点
props(属性)和state(状态)
props
是在父组件中指定,在被指定的组件生命周期中不做改变。如果需要改变的数据,则可以使用state
。
this的绑定
ES6中自定义的函数里面使用this
关键字,需要对其进行绑定操纵,否则this
的指向会指向空。操作示例:
...
constructor(props) {
super(props);
this.state = {
data: [],
loaded: false
},
this.fetchData = this.fetchData.bind(this);
}
fecthData() {
fetch(REQUEST_URL){
this.setState({
data: this.state.data.concat(['name'])
})
}
}
样式编写的几种方式
1. 使用类名
// 单个类名
<View style = { styles.container }>
<Text>some awesome text</Text>
</View>
const styles = StyleSheet.create({
container: {
backgroundColor: '#f8f8f8',
flex: 1
}
})
// 多个类名
<View style = { [styles.container, styles.colorRed]}>
<Text>some awesome text</Text>
</View>
const styles = StyleSheet.create({
container: {
backgroundColor: '#f8f8f8',
flex: 1
},
colorRed: {
color: '#f00'
2. 使用行内样式
<View style = {{ backgroundColor: '#f8f8f8', flex: 1
<Text>some awesome text</Text>
</View>
3. 类名和行内样式结合
<View style = { [styles.container, { color: '#f00' }] }>
<Text>some awesome text</Text>
</View>
const styles = StyleSheet.create({
container: {
backgroundColor: '#f8f8f8',
父子组件的传值
这里没有引入状态管理工具,比如redux。
1. 父组件传值给子组件
通过props进行值的传递
// 父组件
import Child from 'path/to/Child'
<View>
<Child name='jiaming'/>
</View>
// 子组件
render() {
const { name } = this.props;
return(
<View>
<Text> { name } </text>
</View>
2. 子组件传值给父组件
通过props的方法进行传值
// 父组件
import Child from 'path/to/Child'
getValue(data) {
console.log(data);
}
render() {
return (
<View>
<Child getValue = { this.getValue.bind() }>
</View>
)
}
// 子组件
trigger() {
this.props.getValue({
name: 'name from child component'
});
}
render() {
return (
<View>
<Text onPress={ this.trigger.bind(this) }> some awesome text </Text>
</View>
父组件的数据状态变动,子组件的数据没变动?
在父组件中设置了父组件的数据变动了,但是子组件的数据并没有变动。比如:
// 父组件
import Child from 'path/to/Child'
Fn() {
this.setState({
name: 'jiaming'
});
}
<View>
<Child name = { this.state.name
</View>
出现在子组件中数据没变动的话,应该在子组件中做下面的处理:
- 在componentWillReceiveProps钩子内处理
- componentWillReceiveProps钩子函数上传入props参数代替函数内的this.props
相关的案例如下:
componentWillReceiveProps(props) { // props这个参数要加上
const {
name
} = props; // 这里不能使用this.props,不然会造成数据渲染不同步
this.setState({
name: name
});
}
setState中引入变量
在我们改变state值的时候,我们一般都会使用到setState
,比如:
constructor(props){
super(props);
this.state = {
name : ''
}
}
Fn() {
this.setState({
name: 'jiaming'
上面的setState
中的key值是name,那么,如果我使用一个变量代替name需要怎么写呢?
答:使用中括号[]
来包裹就行了。如下demo
Fn() {
const _name = 'jiaming';
this.setState({
[_name]: 'jiaming'
render return
内的条件判断写法
在View
页面内,很多时候是需要你根据条件判断进行,那么相关的写法你可以包裹在一个大括号{}
里面的。比如:
constructor(props){
super(props);
this.state = {
typeFlag: 1
}
}
render() {
return (
<View>
{
typeFlag == 1 ?
<Text>type flag is one</Text>
:
typeFlag == 2 ?
<Text>type flag is two</Text>
:
null
}
</View>
使用Modal会遮住下层的内容
在开始时候,引入Modal
之后是,执行了相关的代码,弹出了Modal
之后,是看不到下层的内容的,这很是不合理。解决方案:引入属性transparent
。
如下:
render() {
return (
<Modal
animationType='slide'
transparent='true'>
<View>
<Text>some awesome text</Text>
</View>
</Modal>
javascript的引入方式
1. 行内编写
<TouchableOpacity onPress={ () => console.log('this is a demo')}>
<Text>some awesome text</Text>
</TouchableOpacity>
2. 行内引入指针
handleEvent() {
console.log('this is a demo');
}
<TouchableOpacity onPress={ this.handleEvent.bind(this) }>
<Text>some awesome text</Text>
</TouchableOpacity>
navigation内的事件编写
在react native navigation
中直接使用类似this.handleMethod
这种方法是不生效的,比如:
static navigationOptions = ({navigation}) => ({
headerLeft: (
<TouchableOpacity onPress = { this.handleMothed.bind(this) }>
<Text style={{ color: '#999', paddingLeft: 10}}>返回</Text>
</TouchableOpacity>
)
});
handleMothed(){
console.log('this is a demo');
}
你应该这样写(使用this.props.navigation.setParams
):
static navigationOptions = ({navigation}) => ({
headerRight: (
<TouchableOpacity onPress= {()=>navigation.state.params.handleComfirm()} >
<Text style={{ color: '#999', paddingLeft: 10}}>确认</Text>
</TouchableOpacity>
)
)
});
componentDidMount() {
// 组件加载完之后操作
this.props.navigation.setParams({handleComfirm:this.handleComfirm})
}
handleComfirm() {
console.log('this is a demo');
}
mac上安装的安卓adb
使用brew安装。
- 默认已经安装了brew
- brew cask install android-platform-tools // Install adb
- adb devices // Start using adb
⚠️在安装的过程中,请保持网络的顺畅。
参考链接:www.jianshu.com/p/bb74ae9d2…
后话
文章部分内容的引用已丢失,若有雷同,不胜荣幸。如有错误,还望看官纠正。
更多的内容请前往我的博客