摘要:組件將元素作為結(jié)果返回。是把數(shù)據(jù)從項目傳到的有效載荷。有以下職責維持應用的提供方法獲取提供方法更新通過注冊監(jiān)聽器通過返回的函數(shù)注銷監(jiān)聽器。系列目錄前端大統(tǒng)一時代即將來臨項目實戰(zhàn)環(huán)境搭建項目實戰(zhàn)基本原理項目實戰(zhàn)登錄頁面編輯中
React相關
React 是一個采用聲明式,高效而且靈活的用來構建用戶界面的框架。
JSX本質(zhì)上來講,JSX 只是為React.createElement(component, props, ...children)方法提供的語法糖。比如下面的代碼:
const element = (Hello, world!
);
編譯為:
const element = React.createElement( "h1", {className: "greeting"}, "Hello, world!" );
React.createElement()這個方法首先會進行一些避免bug的檢查,之后會返回一個類似下面例子的對象:
const element = { type: "h1", props: { className: "greeting", children: "Hello, world" } };
這樣的對象被稱為React元素,它代表所有你在屏幕上看到的東西。
我們用 React 開發(fā)應用時一般只會定義一個根節(jié)點。要將 React 元素渲染到根DOM節(jié)點中,我們通過把它們都傳遞給ReactDOM.render()的方法來將其渲染到頁面上:
ReactDOM.render( element, document.getElementById("root") );
每當 React 元素發(fā)生變化時,ReactDOM首先會比較元素內(nèi)容先后的不同,然后操作瀏覽器DOM更新改變了的部分。
組件 & Props當 React 遇到的元素是用戶自定義的組件,它會將 JSX 屬性作為單個對象傳遞給該組件,這個對象稱之為props。無論是使用函數(shù)或是類來聲明一個組件,它決不能修改它自己的 props 。
例如,這段代碼會在頁面上渲染出Hello,Sara:
//使用 ES6 class 來定義一個組件,組件名稱必須以大寫字母開頭。 class Welcome extends React.Component { render() { returnHello, {this.props.name}
; } } const element =; ReactDOM.render( element, document.getElementById("root") );
我們來回顧一下在這個例子中發(fā)生了什么:
我們對
React 將{name: "Sara"}作為props傳入并調(diào)用 Welcome 組件。
Welcome 組件將Hello, Sara
元素作為結(jié)果返回。
ReactDOM 將DOM更新為Hello, Sara
。
組件的通過props獲取屬性,且其不能修改;當我們需要修改當前組件的狀態(tài)時,要用到state來設置局部狀態(tài),需要通過this.setState()來更新組件局部狀態(tài):
class Toggle extends React.Component { constructor(props) { super(props); //初始化this,并賦值this.props this.state = {isToggleOn: true}; //初始化this.state this.handleClick = this.handleClick.bind(this); //為this.handleClick綁定this對象 } handleClick() { this.setState(prevState => ({ isToggleOn: !prevState.isToggleOn })); //用this.setState()更新this.state } render() { return ( ); } } ReactDOM.render(, document.getElementById("root") );
每一個組件都有幾個你可以重寫以讓代碼在處理環(huán)節(jié)的特定時期運行的“生命周期方法”。方法中帶有前綴will的在特定環(huán)節(jié)之前被調(diào)用,而帶有前綴did的方法則會在特定環(huán)節(jié)之后被調(diào)用。
裝配:這些方法會在組件實例被創(chuàng)建和插入DOM中時被調(diào)用:
- constructor(`props`) - componentWillMount() - render() - componentDidMount()
更新:屬性或狀態(tài)的改變會觸發(fā)一次更新。當一個組件在被重渲時,這些方法將會被調(diào)用:
- componentWillReceiveProps(`nextProps`) - shouldComponentUpdate(`nextProps`, `nextState`) - componentWillUpdate(`nextProps`, `nextState`) - render() - componentDidUpdate(`prevProps`, `prevState`)
卸載:當一個組件被從DOM中移除時,該方法被調(diào)用:
- componentWillUnmount()
當項目視圖交互復雜且頻繁的時候,依舊采用 state 進行狀態(tài)更改會顯得異常繁瑣和不可預測。
這時我們就需要借助 Redux 框架,將狀態(tài)數(shù)據(jù)全部轉(zhuǎn)交給 Redux 處理,React 專一負責視圖顯示,這樣會讓項目邏輯變得簡單而清晰。
三大原則:
整個應用的 state 被儲存在一棵 object tree 中,并且這個 object tree 只存在于唯一一個store中。
惟一改變 state 的方法就是觸發(fā)action,action 是一個用于描述事件的普通對象。
為了描述 action 如何改變 state tree ,你需要編寫reducers。
ActionAction 是把數(shù)據(jù)從項目傳到 store 的有效載荷。它是 store 數(shù)據(jù)的唯一來源。通常你會通過store.dispatch()將 action 傳到 store。
Action 本質(zhì)上是 JavaScript 普通對象,添加新 todo 任務的 action 是這樣的:
{ type: "ADD_TODO", text: "Build my first Redux app" }
Action 創(chuàng)建函數(shù)就是生成 action 的方法。在 Redux 中的 action 創(chuàng)建函數(shù)只是簡單的返回一個 action:
function addTodo(text) { return { type: "ADD_TODO", text: text } }
這樣做將使 action 創(chuàng)建函數(shù)更容易被移植和測試。只需把 action 創(chuàng)建函數(shù)的結(jié)果傳給 dispatch() 方法即可發(fā)起一次 dispatch 過程。
dispatch(addTodo(text)); //或者創(chuàng)建一個 被綁定的 action 創(chuàng)建函數(shù) 來自動 dispatch: const boundAddTodo = (text) => dispatch(addTodo(text)); boundAddTodo(text);
store 里能直接通過 store.dispatch() 調(diào)用 dispatch() 方法,但是多數(shù)情況下你會使用 react-redux 提供的connect()幫助器來調(diào)用。
ReducerAction 只是描述了有事情發(fā)生了這一事實,而reducer要做的事情正是指明應用如何更新 state 。reducer 就是一個純函數(shù),接收舊的 state 和 action,返回新的 state。
(previousState, action) => newState
保持 reducer 純凈非常重要。永遠不要在 reducer 里做這些操作:
修改傳入?yún)?shù);
執(zhí)行有副作用的操作,如 API 請求和路由跳轉(zhuǎn);
調(diào)用非純函數(shù),如 Date.now() 或 Math.random()。
我們將以指定 state 的初始狀態(tài)作為開始。Redux 首次執(zhí)行時,state 為 undefined,此時我們可借機設置并返回應用的初始 state:
const initialState = {}; //初始化state function todoApp(state = initialState, action) { switch (action.type) { case "ADD_TODO": return Object.assign({}, state, { text: action.text }) default: return state //在 default 情況下返回舊的 state } }
每個 reducer 只負責管理全局 state 中它負責的一部分。每個 reducer 的 state 參數(shù)都不同,分別對應它管理的那部分 state 數(shù)據(jù)。
combineReducers()所做的只是生成一個函數(shù),這個函數(shù)來調(diào)用你的一系列 reducer,每個 reducer 根據(jù)它們的 key 來篩選出 state 中的一部分數(shù)據(jù)并處理,然后這個生成的函數(shù)再將所有 reducer 的結(jié)果合并成一個大的對象。
import { combineReducers } from "redux"; const todoApp = combineReducers({ visibilityFilter, todos }) export default todoApp;
注意上面的寫法和下面完全等價:
export default function todoApp(state = {}, action) { return { visibilityFilter: visibilityFilter(state.visibilityFilter, action), todos: todos(state.todos, action) } }
StorecombineReducers 接收一個對象,可以把所有頂級的 reducer 放到一個獨立的文件中,通過 export 暴露出每個 reducer 函數(shù),然后使用 import * as reducers 得到一個以它們名字作為 key 的 object:
import { combineReducers } from "redux" import * as reducers from "./reducers" const todoApp = combineReducers(reducers)
action 描述發(fā)生了什么,reducers 根據(jù) action 更新 state,Store就是把它們聯(lián)系到一起的對象。Store 有以下職責:
維持應用的 state;
提供getState()方法獲取 state;
提供dispatch(action)方法更新state;
通過subscribe(listener)注冊監(jiān)聽器;
通過subscribe(listener)返回的函數(shù)注銷監(jiān)聽器。
我們使用 combineReducers() 將多個 reducer 合并成為一個?,F(xiàn)在我們將其導入,并傳遞 createStore()。
import { createStore } from "redux" import todoApp from "./reducers" let store = createStore(todoApp)
createStore() 的第二個參數(shù)是可選的, 用于設置 state 初始狀態(tài)。這對開發(fā)同構應用時非常有用,服務器端 redux 應用的 state 結(jié)構可以與客戶端保持一致, 那么客戶端可以將從網(wǎng)絡接收到的服務端 state 直接用于本地數(shù)據(jù)初始化。
let store = createStore(todoApp, window.STATE_FROM_SERVER);數(shù)據(jù)流
Redux 應用中數(shù)據(jù)的生命周期遵循下面 4 個步驟:
調(diào)用 store.dispatch(action)。
Redux store 調(diào)用傳入的 reducer 函數(shù)。
根 reducer 應該把多個子 reducer 輸出合并成一個單一的 state 樹。
Redux store 保存了根 reducer 返回的完整 state 樹。
Router相關直接使用整合后的react-router-redux,后面抽時間再詳細講一下,具體使用的話模仿官方案例吧,官方文檔。
容器組件 和 展示組件Redux 的 React 綁定庫包含了 容器組件和展示組件相分離 的開發(fā)思想。
明智的做法是只在最頂層組件(如路由操作)里使用 Redux。其余內(nèi)部組件僅僅是展示性的,所有數(shù)據(jù)都通過 props 傳入。
系列目錄前端大統(tǒng)一時代即將來臨?
React項目實戰(zhàn):環(huán)境搭建
React項目實戰(zhàn):react-redux-router基本原理
React項目實戰(zhàn):登錄頁面(編輯中)
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/90024.html
摘要:組件將元素作為結(jié)果返回。是把數(shù)據(jù)從項目傳到的有效載荷。有以下職責維持應用的提供方法獲取提供方法更新通過注冊監(jiān)聽器通過返回的函數(shù)注銷監(jiān)聽器。系列目錄前端大統(tǒng)一時代即將來臨項目實戰(zhàn)環(huán)境搭建項目實戰(zhàn)基本原理項目實戰(zhàn)登錄頁面編輯中 React相關 React 是一個采用聲明式,高效而且靈活的用來構建用戶界面的框架。 JSX 本質(zhì)上來講,JSX 只是為React.createElement(co...
摘要:官方文檔中文翻譯構建用戶界面的庫。官方文檔建議學習時以官方文檔為準,中文翻譯或者第三方作者的教程可以幫助你理清思路會用到的重要知識點我也會進行簡明的解釋,如遇到錯誤或者不理解的內(nèi)容,歡迎實時指出。 前言 前面提到前端大統(tǒng)一的概念,如果感興趣,歡迎說說自己的看法,點擊前往。Web前端框架層出不窮,不可能面面俱到,這里給個小建議: 如果對Weex App感興趣,應該選擇vue框架; 如果...
摘要:官方文檔中文翻譯構建用戶界面的庫。官方文檔建議學習時以官方文檔為準,中文翻譯或者第三方作者的教程可以幫助你理清思路會用到的重要知識點我也會進行簡明的解釋,如遇到錯誤或者不理解的內(nèi)容,歡迎實時指出。 前言 前面提到前端大統(tǒng)一的概念,如果感興趣,歡迎說說自己的看法,點擊前往。Web前端框架層出不窮,不可能面面俱到,這里給個小建議: 如果對Weex App感興趣,應該選擇vue框架; 如果...
該demo使用的是webpack2.*來配置的,很多配置項都產(chǎn)生了變化,踩了不少坑.目前還在逐步完善中,webpack是一部一部配置來的。后端數(shù)據(jù)使用nodejs來開發(fā)模擬。GitHub項目地址。 showImg(https://segmentfault.com/img/remote/1460000009665620); 歡迎大家提問題。
摘要:項目地址項目預覽登錄流負責全局的登錄狀態(tài)管理??傮w思想所有的組件都盡量是所有的狀態(tài)組件一般都是路由組件。所有的分發(fā)都交給了路由組件來完成。數(shù)據(jù)的獲取有兩種方式。一種是官方推薦的使用在訂閱數(shù)據(jù)源。 項目地址 https://github.com/HeskeyBaoz... 項目預覽 showImg(https://segmentfault.com/img/bVIQHX?w=1249&h=...
閱讀 3077·2021-11-18 10:07
閱讀 3854·2021-11-17 17:00
閱讀 2167·2021-11-15 18:01
閱讀 986·2021-10-11 10:58
閱讀 3513·2021-09-10 10:50
閱讀 3675·2021-08-13 15:05
閱讀 1279·2019-08-30 15:53
閱讀 2711·2019-08-29 13:01