關於React native 的總結和筆記
React Native 複習
生命週期
- 元件的生命週期分三個狀態
- Mounting(裝載) 已插入真是的DOM
- Updating 正在被重新渲染
- UNMounting 已移出真實的DOM
Mounting(裝載)
getInitialState(): 在元件掛載之前呼叫一次。返回值將會作為 this.state 的初始值。
componentWillMount():伺服器端和客戶端都只調用一次,在初始化渲染執行之前立刻呼叫。
componentDidMount():在初始化渲染執行之後立刻呼叫一次,僅客戶端有效(伺服器端不會呼叫)。
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.xxx 獲取元件屬性,物件的屬性可以任意定義,但要避免與Js關鍵字的衝突
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
- 箭頭函式
- 函式的快捷寫法,不需要通過 function 關鍵字建立函式,並且還可以省略 return 關鍵字。
- 同時,箭頭函式還會繼承當前上下文的 this 關鍵字。
- 比如:
[1, 2, 3].map(x => x + 1); // [2, 3, 4] - 等同於:
[1, 2, 3].map((function(x) {
return x + 1;
}).bind(this));
- 比如:
模組的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’, ‘b’, ‘c’); // [‘b’, ‘c’]; 代替 apply。
function foo(x, y, z) {}
const args = [1,2,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
- Component 巢狀
- 類似於HTML,JSX裡面可以給元件新增子元件
- 類似於HTML,JSX裡面可以給元件新增子元件
- className
- class 是保留詞,所以新增樣式時,需用 className 代替 class 。
- JavaScript 表示式
- JavaScript 表示式需要用 {} 括起來,會執行並返回結果。
- 比如:
{ this.props.title }
- Component 巢狀
Props
資料處理在 React 中是非常重要的概念之一,分別可以通過 props, state 和 context 來處理資料。而在 dva 應用裡,你只需關心 props 。propsType
- JavaScript 是弱型別語言,所以請儘量宣告 propTypes 對 props 進行校驗,以減少不必要的問題。
function App(props) {
return {props.name};
}
App.propTypes = {
name: React.PropTypes.string.isRequired,
}; - 內建的 prop type 有:
- PropTypes.array
- PropTypes.bool
- PropTypes.func
- PropTypes.number
- PropTypes.object
- PropTypes.string
往下傳資料
往上傳資料
- JavaScript 是弱型別語言,所以請儘量宣告 propTypes 對 props 進行校驗,以減少不必要的問題。
理解CSS Modules
結構說明
- button class 在構建之後會被重新命名為 ProductList_button_1FU0u 。button 是 local name,而 ProductList_button_1FU0u是 global name 。你可以用簡短的描述性名字,而不需要關心命名衝突問題。
- 然後你要做的全部事情就是在 css/less 檔案裡寫 .button {…},並在元件裡通過 styles.button 來引用他。
- 定義全域性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