React Native 复习
生命周期
- 组件的生命周期分三个状态
- Mounting(装载) 已插入真是的DOM
- Updating 正在被重新渲染
- UNMounting 已移出真实的DOM
Mounting(装载)
getInitialState(): 在组件挂载之前调用一次。返回值将会作为 this.state 的初始值。
Updating(更新)
- componentWillReceiveProps(object nextProps) 在组件接收到新的 props 的时候调用。在初始化渲染的时候,该方法不会调用。
- shouldComponentUpdate(object nextProps,object nextState): 在接收到新的 props 或者 state,将要渲染之前调用。
componentWillUpdate(object nextProps,object nextState):在接收到新的 props 或者 state 之前立刻调用。在初始化渲染的时候该方法不会被调用。使用该方法做一些更新之前的准备工作。
注意:你不能在该方法中使用 this.setState()。如果需要更新 state 来响应某个 prop 的改变,请使用 componentWillReceiveProps。componentDidUpdate(object prevProps,object prevState): 在组件的更新已经同步到 DOM 中之后立刻被调用。
该方法不会在初始化渲染的时候调用。使用该方法可以在组件更新之后操作 DOM 元素。
Unmounting (移除)
componentWillUnmount:在组件从 DOM 中移除的时候立刻被调用。
在该方法中执行任何必要的清理,比如无效的定时器,或者清除在 componentDidMount 中创建的 DOM 元素。- Component 与 PureComponent
- 操作延展符 {…pramas}
- 组件的属性(Props)
- 每个组件只会根据props 渲染了自己一次,props 是不可变的。
this.props.children 返回组件对象的所有属性
- 组件的类型PropTypes 可以接收任意类型值,字符串,对象,函数等等都可以。
1 . ref属性(获取真实的DOM节点)
- 组件并不是真实的DOM节点
- 组件的render方法被调用时,ref才会被调用,组件才会返回ref。如果你在调用this.refs.xx时render方法还没被调用,那么你得到的是undefined。
2 . state 状态
- this.state 是组件私有的,可以通过getInitialState()方法初始化,通过调用 this.setState() 来改变它。当 state 更新之后,组件就会重新渲染自己。
- render() 方法依赖于 this.props 和 this.state ,框架会确保渲染出来的 UI 界面总是与输入( this.props 和 this.state )保持一致。
3 . render 方法是必须的。
- 当该方法被回调的时候,会检测 this.props 和 this.state,并返回一个单子级组件。
- render()函数应该是纯粹的,也就是说该函数不修改组件的 state,每次调用都返回相同的结果,不读写 DOM 信息,也不和浏览器交互(例如通过使用 setTimeout)。如果需要和浏览器交互,在 componentDidMount() 中或者其它生命周期方法中做这件事。保持 render() 纯粹,可以使服务器端渲染更加切实可行,也使组件更容易被理解。
- 不要在render()函数中做复杂的操作,更不要进行网络请求,数据库读写,I/O等操作。
4 . getInitalState() 初始化组件状态
- 在组件挂载之前调用一次。返回值将会作为 this.state的初始值。
- 通常在该方法中对组件的状态进行初始化。
5 . getDefaultProps() 设置组件属性的默认值
- 在组件类创建的时候调用一次,然后返回值被缓存下来。
- 如果父组件没有指定 props 中的某个键,则此处返回的对象中的相应属性将会合并到 this.props
- 该方法在任何实例创建之前调用,因此不能依赖于 this.props
- getDefaultProps() 返回的任何复杂对象将会在实例间共享,而不是每个实例拥有一份拷贝。
- 该方法在你封装一个自定义组件的时候经常用到,通常用于为组件初始化默认属性。
6 . 箭头函数 (Arrow)
- =>不只是关键字function的简写,它还带来了其它好处。箭头函数与包围它的代码共享同一个this,能帮你很好的解决this的指向问题。
- 箭头函数的箭头=>之前是一个空括号、单个的参数名、或用括号括起的多个参数名,而箭头之后可以是一个表达式(作为函数的返回值),或者是用花括号括起的函数体(需要自行通过return来返回值,否则返回的是undefined)。
// 箭头函数的例子
()=>1
v=>v+1
(a,b)=>a+b
()=>{
alert("foo");
}
e=>{
if (e == 0){
return 0;
}
return 1000/e;
}
不论是箭头函数还是bind,每次被执行都返回的是一个新的函数引用,因此如果你还需要函数的引用去做一些别的事情(譬如卸载监听器),那么你必须自己保存这个引用。
Redux 复习
单向数据流
- action
- actionCreater 就是一个函数
var actionCreater = function(){
return {`这里写代码片`
type:'AN_ACTION'
}
}
- 约定action 是有一个type属性的对象,然后按照type决定如何处理action。 - 当然也可以有其他属性,可以存放任意想要的数据 => payload - 一般情况下默认导出,供相应的触发事件调用。
2. Redux提供了
- 存放应用程序状态的容器
- 一种把action 分发到状态修改器的机制,也就是reducer函数
- 监听状态变化机制
javaScript总结
变量声明
const 和 let
不要用 var,而是用 const 和 let,分别表示常量和变量。不同于 var 的函数作用域,const 和 let 都是块级作用域。
const DELAY = 1000;let count = 0;
count = count + 1;模板字符串
模板字符串提供了另一种做字符串组合的方法。
const user = ‘world’;
console.log(hello ${user}
); // hello world// 多行
const content =
Hello ${firstName},
Thanks for ordering ${qty} tickets to ${event}.
默认参数
function logActivity(activity = ‘skiing’) {
console.log(activity);
}logActivity(); // skiing
- 箭头函数
模块的import 和export
import 用于引入模块,export 用于导出模块。
// 引入全部
import dva from ‘dva’;// 引入部分
import { connect } from ‘dva’;
import { Link,Route } from ‘dva/router’;// 引入全部并作为 github 对象
import * as github from ‘./services/github’;// 导出默认
export default App;
// 部分导出,需 import { App } from ‘./file’; 引入
export class App extend Component {};
ES6 对象和数组
析构赋值
赋值让我们从 Object 或 Array 里取部分数据存为变量。
// 对象
const user = { name: ‘guanguan’,age: 2 };
const { name,age } = user;
console.log(${name} : ${age}
); // guanguan : 2// 数组
const arr = [1,2];
const [foo,bar] = arr;
console.log(foo); // 1- 我们也可以析构传入的函数参数。
const add = (state,{ payload }) => {
return state.concat(payload);
}; - 析构时还可以配 alias,让代码更具有语义。
const add = (state,{ payload: todo }) => {
return state.concat(todo);
};
对象字面量改进
这是析构的反向操作,用于重新组织一个 Object 。
const name = ‘duoduo’;
const age = 8;const user = { name,age }; // { name: ‘duoduo’,age: 8 }
- 定义对象方法时,还可以省去 function 关键字。
app.model({
reducers: {
add() {} // 等同于 add: function() {}
},
effects: {
addRemote() {} // 等同于 addRemote: function() {}
},
});
Spread Operator(操作延展符 … )
- Spread Operator 即 3 个点 …,有几种不同的使用方法。
- 可用于组装数组。
const todos = [‘Learn dva’];
[…todos,‘Learn antd’]; // [‘Learn dva’,‘Learn antd’] 也可用于获取数组的部分项。
const arr = [‘a’,‘b’,‘c’];
const [first,…rest] = arr;
rest; // [‘b’,‘c’]// With ignore
const [first,…rest] = arr;
rest; // [‘c’]- 还可收集函数参数为数组。
function directions(first,…rest) {
console.log(rest);
}
directions(‘a’,‘c’); // [‘b’,‘c’]; 代替 apply。
function foo(x,y,z) {}
const args = [1,3];// 下面两句效果相同
foo.apply(null,args);
foo(…args);对于 Object 而言,用于组合成新的 Object 。
const foo = {
a: 1,
b: 2,
};
const bar = {
b: 3,
c: 2,
};
const d = 4;const ret = { …foo,…bar,d }; // { a:1,b:3,c:2,d:4 }
- 此外,在 JSX 中 Spread Operator( …) 还可用于扩展 props
Promises
- Promise 用于更优雅地处理异步请求。比如发起异步请求:
fetch(‘/api/todos’)
.then(res => res.json())
.then(data => ({ data }))
.catch(err => ({ err })); 定义Promise
const delay = (timeout) => {
return new Promise(resolve => {
setTimeout(resolve,timeout);
});
};delay(1000).then(_ => {
console.log(‘executed’);
})
- Promise 用于更优雅地处理异步请求。比如发起异步请求:
- Generators
- dva 的 effects 是通过 generator 组织的。
- Generator 返回的是迭代器,通过 yield 关键字实现暂停功能。
- 这是一个典型的 dva effect,通过 yield 把异步逻辑通过同步的方式组织起来。
app.model({
namespace: ‘todos’,
effects: {
*addRemote({ payload: todo },{ put,call }) {
yield call(addTodo,todo);
yield put({ type: ‘add’,payload: todo });
},
},
});
React Component
- React Component 有 3 种定义方式,分别是 React.createClass,class 和 Stateless Functional Component。
- 推荐尽量使用最后一种,保持简洁和无状态。
- 这是函数,不是 Object,没有 this 作用域,是 pure function。
- 比如定义 App Component 。
function App(props) {
function handleClick() {
props.dispatch({ type: ‘app/create’ });
}
return${props.name}
} - 等同于:
class App extends React.Componnet {
handleClick() {
this.props.dispatch({ type: ‘app/create’ });
}
render() {
return${this.props.name}
}
}
- 比如定义 App Component 。
- JSX
Props
数据处理在 React 中是非常重要的概念之一,分别可以通过 props,state 和 context 来处理数据。而在 dva 应用里,你只需关心 props 。propsType
理解CSS Modules
结构说明
- 定义全局CSS
- CSS Modules 默认是局部作用域的,想要声明一个全局规则,可用 :global 语法。
- 比如:
.title {
color: red;
}
:global(.title) {
color: green;
} - 然后在引用的时候:
// red
// green
- className Package
- 在一些复杂的场景中,一个元素可能对应多个 className,而每个 className 又基于一些条件来决定是否出现。
- 这时,classnames 这个库就非常有用。 import classnames from ‘classnames’; const App = (props) => { const cls = classnames({ btn: true,btnLarge: props.type === ‘submit’,btnSmall: props.type === ‘edit’,}); return