|
| 1 | +## React Native 基础知识总结 |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | +### Component |
| 6 | +Component:组件,使用`extends React.Component`创建的类为组件。? |
| 7 | + `componentWillMount()`还可以用` constructor `来代替: |
| 8 | + |
| 9 | +```javascript |
| 10 | +class Label extends React.Component{ |
| 11 | + constructor(props) { |
| 12 | + super(props); |
| 13 | + } |
| 14 | + render(){ |
| 15 | + } |
| 16 | +} |
| 17 | +``` |
| 18 | + |
| 19 | +### props与state |
| 20 | + |
| 21 | +##### props属性: |
| 22 | +组件可以定义初始值,自己不可更改props属性值,只允许从父组件中传递过来: |
| 23 | + |
| 24 | +```javascript |
| 25 | +// 父组件 |
| 26 | +class ParentComponent extends React.Component{ |
| 27 | + render(){ |
| 28 | + return(<Child name="name">); |
| 29 | + } |
| 30 | +} |
| 31 | + |
| 32 | +// 子组件 |
| 33 | +class Child extends React.Component{ |
| 34 | + render(){ |
| 35 | + return(<Text>{this.props.name}</Text>); |
| 36 | + } |
| 37 | +} |
| 38 | +``` |
| 39 | + |
| 40 | +父组件向子组件传递name="name"的props属性,在子组件中使用this.props.name引用此属性。 |
| 41 | + |
| 42 | +属性类型``` prop type ```和默认属性 ```default prop ```可以通过类中的 ```static ```来声明: |
| 43 | + |
| 44 | +```javascript |
| 45 | +class Demo extends React.Component { |
| 46 | + // 默认props |
| 47 | + static defaultProps = { |
| 48 | + autoPlay: false, |
| 49 | + maxLoops: 10, |
| 50 | + } |
| 51 | + // propTypes用于验证转入的props,当向 props 传入无效数据时,JavaScript 控制台会抛出警告 |
| 52 | + static propTypes = { |
| 53 | + autoPlay: React.PropTypes.bool.isRequired, |
| 54 | + maxLoops: React.PropTypes.number.isRequired, |
| 55 | + posterFrameSrc: React.PropTypes.string.isRequired, |
| 56 | + } |
| 57 | + state = { |
| 58 | + loopsRemaining: this.props.maxLoops, |
| 59 | + } |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +##### state属性: |
| 64 | +组件用来改变自己状态的属性,通常使用```setState({key:value})```来改变属性值触发界面刷新,不能使用```this.state.xxx```来直接改变。 |
| 65 | +在开发中,一般不会在定时器函数(setInterval、setTimeout等)中来操作state。典型的场景是在接收到服务器返回的新数据,或者在用户输入数据之后。 |
| 66 | + |
| 67 | +对于经常改变的数据且需要刷新界面显示,可以使用state。对于不需要改变的属性值可以使用props。React Native建议由顶层的父组件定义state值,并将state值作为子组件的props属性值传递给子组件,这样可以保持单一的数据传递。 |
| 68 | + |
| 69 | + |
| 70 | + |
| 71 | +###生命周期 |
| 72 | + |
| 73 | +我们把组件从```装载```,到```渲染```,再到```卸载```当做一次生命周期,也就是组件的生存状态从```装载```开始到```卸载```为止,期间可以根据属性的变化进行多次渲染。 |
| 74 | +生命周期的三种状态: |
| 75 | +-Mounting:装载 |
| 76 | +1.componentWillMount() |
| 77 | +2.componentDidMount() |
| 78 | +-Updating:渲染 |
| 79 | +1.componentWillReceiveProps() |
| 80 | +2.shouldComponentUpdate() |
| 81 | +3.componentWillUpdate() |
| 82 | +4.componentDidUpdate() |
| 83 | +-Unmounting:卸载 |
| 84 | +componentWillUnmount() |
| 85 | + |
| 86 | +```javascript |
| 87 | +componentWillMount(),组件开始装载之前调用,在一次生命周期中只会执行一次。 |
| 88 | +componentDidMount(),组件完成装载之后立即调用,在一次生命周期中只会执行一次。在这里开始就可以对组件进行各种操作了,比如在组件装载完成后要显示的时候执行动画。 |
| 89 | +componentWillUpdate(object nextProps, object nextState),当新的props或者state被接受时,组件属性更新之前调用,这个方法不会被初始渲染调用。不能在这个方法里使用 this.setState()。如果你要响应一个prop变化来更新state,使用componentWillReceiveProps 来替代。 |
| 90 | + |
| 91 | +componentDidUpdate(object prevProps, object prevState),组件属性更新之后调用,每次属性更新都会调用,这个方法不会被初始渲染调用。 |
| 92 | +componentWillUnmount(),组件卸载之前调用,在这个方法里执行一些必要的清理操作,比如timers。 |
| 93 | +``` |
| 94 | + |
| 95 | +##### 组件属性更改时会调用以下方法,在一次生命周期中可以执行多次: |
| 96 | + |
| 97 | +```javascript |
| 98 | +componentWillReceiveProps(object nextProps),已加载组件收到新的props时被调用.这个方法不会为最初的渲染调用。 |
| 99 | + |
| 100 | +shouldComponentUpdate(object nextProps, object nextState),组件判断是否重新渲染时调用,当新的props或者state被收到,在渲染前被调用.这个方法不会在最初的渲染被调用。 |
| 101 | +``` |
| 102 | + |
| 103 | +并没有类似的 ```componentWillReceiveState ()```的方法。一个即将到来的 prop 转变可能会导致一个 state 变化,但是反之不是。如果你需要实现一个对 state 变化相应的操作,使用 ```componentWillUpdate()```。 |
| 104 | + |
| 105 | + |
| 106 | +如果 shouldComponentUpdate () 返回false, render() 会在下次state变化前被完全跳过。另外componentWillUpdate () 和 componentDidUpdate() 将不会被调用。 |
| 107 | + |
| 108 | +默认情况下shouldComponentUpdate() 总是返回 true 来阻止当 state 突变时的细微bug。 |
| 109 | + |
| 110 | + |
| 111 | +### 页面跳转 |
| 112 | + |
| 113 | +初始化第一个页面: |
| 114 | + |
| 115 | +```javascript |
| 116 | +import SeatPageComponent from './SeatPageComponent'; |
| 117 | +import MainPageComponent from './MainPageComponent'; |
| 118 | +import TrainListComponent from './TrainListComponent'; |
| 119 | + |
| 120 | +class MainPage extends React.Component { |
| 121 | + render() { |
| 122 | + let defaultName = 'MainPageComponent'; |
| 123 | + let defaultComponent = MainPageComponent; |
| 124 | + return ( |
| 125 | + <Navigator |
| 126 | + // 指定默认页面 |
| 127 | + initialRoute={{ name: defaultName, component: defaultComponent }} |
| 128 | + // 配置页面间跳转动画 |
| 129 | + configureScene={(route) => { |
| 130 | + return Navigator.SceneConfigs.VerticalDownSwipeJump; |
| 131 | + }} |
| 132 | + // 初始化默认页面 |
| 133 | + renderScene={(route, navigator) => { |
| 134 | + let Component = route.component; |
| 135 | + // 将navigator作为props传递到下一个页面 |
| 136 | + return <Component {...route.params} navigator={navigator} /> |
| 137 | + }} /> |
| 138 | + ); |
| 139 | + } |
| 140 | +} |
| 141 | + |
| 142 | +``` |
| 143 | + |
| 144 | +跳转到下一页面: |
| 145 | + |
| 146 | +```javascript |
| 147 | +jumpToNext(){ |
| 148 | + const { navigator } = this.props;// 由上一个页面传递过来 |
| 149 | + if(navigator) { |
| 150 | + navigator.push({ |
| 151 | + name: 'SeatPageComponent', |
| 152 | + component: SeatPageComponent,// 下一个页面 |
| 153 | + }); |
| 154 | + } |
| 155 | +} |
| 156 | +``` |
| 157 | + |
| 158 | +返回上一个页面: |
| 159 | + |
| 160 | +```javascript |
| 161 | + _back(){ |
| 162 | + const { navigator } = this.props; |
| 163 | + if(navigator) { |
| 164 | + navigator.pop(); |
| 165 | + } |
| 166 | + } |
| 167 | +``` |
| 168 | + |
| 169 | +页面间通信 |
| 170 | + |
| 171 | +例如:从A页面打开B页面 |
| 172 | +A通过route.params将参数传递给B: |
| 173 | + |
| 174 | +```javascript |
| 175 | +jumpToNext(){ |
| 176 | + const { navigator } = this.props;// 由上一个页面传递过来 |
| 177 | + if(navigator) { |
| 178 | + navigator.push({ |
| 179 | + name: 'SeatPageComponent', |
| 180 | + component: SeatPageComponent,// 下一个页面 |
| 181 | + params: { // 需要传递个下一个页面的参数,第二个页面使用this.props.xxx获取参数 |
| 182 | + id: 123, |
| 183 | + title: this.state.title, |
| 184 | + }, |
| 185 | + }); |
| 186 | + } |
| 187 | +} |
| 188 | +``` |
| 189 | + |
| 190 | +A通过route.params传递回调方法或者A的引用来让B将数据传回给A: |
| 191 | + |
| 192 | +```javascript |
| 193 | +// A页面 |
| 194 | +jumpToNext(){ |
| 195 | + const { navigator } = this.props;// 由上一个页面传递过来 |
| 196 | + if(navigator) { |
| 197 | + let that = this;// this作用域,参见下文函数绑定 |
| 198 | + navigator.push({ |
| 199 | + name: 'SeatPageComponent', |
| 200 | + component: SeatPageComponent,// 下一个页面 |
| 201 | + params: { // 需要传递个下一个页面的参数,第二个页面使用this.props.xxx获取参数 |
| 202 | + title: '测试', |
| 203 | + getName: function(name) {that.setState({ name: name })} |
| 204 | + }, |
| 205 | + }); |
| 206 | + } |
| 207 | +} |
| 208 | + |
| 209 | +// B页面 |
| 210 | + _back(){ |
| 211 | + const { navigator } = this.props; |
| 212 | + if(this.props.getName){ |
| 213 | + this.props.getName('测试'); |
| 214 | + } |
| 215 | + if(navigator) { |
| 216 | + navigator.pop(); |
| 217 | + } |
| 218 | + } |
| 219 | +``` |
| 220 | + |
| 221 | + |
| 222 | +### flexbox布局 |
| 223 | +##### 什么是flexbox布局 |
| 224 | +React中引入了flexbox概念,flexbox是属于web前端领域CSS的一种布局方案,是2009年W3C提出了一种新的布局方案,可以简便、完整、响应式地实现各种页面布局。 |
| 225 | +RN利用flexBox模型布局, 也就是在手机屏幕上对组件进行排列.利用flexBox模型,开发者可以开发出动态宽高的自适应的UI布局。 |
| 226 | + |
| 227 | +##### flexbox中的样式主要有以下几类: |
| 228 | +1. 位置及宽、高相关的样式键 |
| 229 | +2. 容器属性,决定子组件排列规则的键 |
| 230 | +3. 元素属性,决定组件显示规则的键 |
| 231 | +4. 边框、空隙与填充 |
| 232 | + |
| 233 | +#####布局样式 |
| 234 | +- position |
| 235 | + ```relative```(默认) 表示当前描述的位置是相对定位,不可以使用``` bottom```和```right```。```top```和```left```表示当前组件距离上一个同级组件的最上(左)距离 |
| 236 | + ```absolute``` 表示当前描述的位置是绝对定位,``` top``` 、```bottom```、``` left```、 ```right```,描述当前组件的位置距离父组件最(上下、左、右)的距离 |
| 237 | +- width |
| 238 | + ```width```、```height```、```maxHeight```、```maxWidth```、```minHeight```、```minWidth``` 组件的宽和高是可以动态改变的,所以可以设置宽和高的最大和最小值 |
| 239 | +- flexDirection |
| 240 | + ```row```:横向排列,<b>主轴</b>为水平方向; |
| 241 | + ```?column```:竖直排列,<b>主轴</b>为垂直方向。 |
| 242 | +- flexWrap |
| 243 | + ```?wrap ```?和 ```?nowrap ```?(默认值)?,当水平或垂直布局时,如果子View放不下可选 ```?wrap ```?实现自动换行, |
| 244 | +- justifyContent |
| 245 | +子布局在主轴方向位置 enum(```flex- start```,```flex-end```,```center```,```space-between```,```space-around```) |
| 246 | +- alignItems |
| 247 | + 子布局在侧轴方向位置 enum(```flex-start```,```flex-end```,```center```,```stretch``` ) |
| 248 | +- flex |
| 249 | + 权重,默认值是0当它的值为1时,子组件将自动缩放以适应父组件剩下的空白空间。 |
| 250 | +- alignSelf |
| 251 | + 忽略它的父组件样式中的```alignItems```的取值,而对该组件使用```alignSelf```键对应的规则。 |
| 252 | +enum(```auto```,```flex-start```,```flex-end```,```center```,```stretch```) |
| 253 | +- padding |
| 254 | +- margin |
| 255 | + |
| 256 | + |
| 257 | + |
| 258 | + |
| 259 | + |
0 commit comments