成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

React項(xiàng)目實(shí)戰(zhàn):react-redux-router基本原理

MorePainMoreGain / 2004人閱讀

摘要:組件將元素作為結(jié)果返回。是把數(shù)據(jù)從項(xiàng)目傳到的有效載荷。有以下職責(zé)維持應(yīng)用的提供方法獲取提供方法更新通過注冊(cè)監(jiān)聽器通過返回的函數(shù)注銷監(jiān)聽器。系列目錄前端大統(tǒng)一時(shí)代即將來臨項(xiàng)目實(shí)戰(zhàn)環(huán)境搭建項(xiàng)目實(shí)戰(zhàn)基本原理項(xiàng)目實(shí)戰(zhàn)登錄頁面編輯中

React相關(guān)

React 是一個(gè)采用聲明式,高效而且靈活的用來構(gòu)建用戶界面的框架。

JSX

本質(zhì)上來講,JSX 只是為React.createElement(component, props, ...children)方法提供的語法糖。比如下面的代碼:

const element = (
  

Hello, world!

);

編譯為:

const element = React.createElement(
  "h1",
  {className: "greeting"},
  "Hello, world!"
);

React.createElement()這個(gè)方法首先會(huì)進(jìn)行一些避免bug的檢查,之后會(huì)返回一個(gè)類似下面例子的對(duì)象:

const element = {
  type: "h1",
  props: {
    className: "greeting",
    children: "Hello, world"
  }
};

這樣的對(duì)象被稱為React元素,它代表所有你在屏幕上看到的東西。
我們用 React 開發(fā)應(yīng)用時(shí)一般只會(huì)定義一個(gè)根節(jié)點(diǎn)。要將 React 元素渲染到根DOM節(jié)點(diǎn)中,我們通過把它們都傳遞給ReactDOM.render()的方法來將其渲染到頁面上:

ReactDOM.render(
  element,
  document.getElementById("root")
);

每當(dāng) React 元素發(fā)生變化時(shí),ReactDOM首先會(huì)比較元素內(nèi)容先后的不同,然后操作瀏覽器DOM更新改變了的部分。

組件 & Props

當(dāng) React 遇到的元素是用戶自定義的組件,它會(huì)將 JSX 屬性作為單個(gè)對(duì)象傳遞給該組件,這個(gè)對(duì)象稱之為props。無論是使用函數(shù)或是類來聲明一個(gè)組件,它決不能修改它自己的 props 。
例如,這段代碼會(huì)在頁面上渲染出Hello,Sara:

//使用 ES6 class 來定義一個(gè)組件,組件名稱必須以大寫字母開頭。
class Welcome extends React.Component {
  render() {
    return 

Hello, {this.props.name}

; } } const element = ; ReactDOM.render( element, document.getElementById("root") );

我們來回顧一下在這個(gè)例子中發(fā)生了什么:

我們對(duì)元素調(diào)用了ReactDOM.render()方法。

React 將{name: "Sara"}作為props傳入并調(diào)用 Welcome 組件。

Welcome 組件將

Hello, Sara

元素作為結(jié)果返回。

ReactDOM 將DOM更新為

Hello, Sara

。

State & 生命周期

組件的通過props獲取屬性,且其不能修改;當(dāng)我們需要修改當(dāng)前組件的狀態(tài)時(shí),要用到state來設(shè)置局部狀態(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對(duì)象
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));    //用this.setState()更新this.state
  }

  render() {
    return (
      
    );
  }
}

ReactDOM.render(
  ,
  document.getElementById("root")
);

每一個(gè)組件都有幾個(gè)你可以重寫以讓代碼在處理環(huán)節(jié)的特定時(shí)期運(yùn)行的“生命周期方法”。方法中帶有前綴will的在特定環(huán)節(jié)之前被調(diào)用,而帶有前綴did的方法則會(huì)在特定環(huán)節(jié)之后被調(diào)用。

裝配:這些方法會(huì)在組件實(shí)例被創(chuàng)建和插入DOM中時(shí)被調(diào)用:

- constructor(`props`)
- componentWillMount()
- render()
- componentDidMount()

更新:屬性或狀態(tài)的改變會(huì)觸發(fā)一次更新。當(dāng)一個(gè)組件在被重渲時(shí),這些方法將會(huì)被調(diào)用:

- componentWillReceiveProps(`nextProps`)
- shouldComponentUpdate(`nextProps`, `nextState`)
- componentWillUpdate(`nextProps`, `nextState`)
- render()
- componentDidUpdate(`prevProps`, `prevState`)

卸載:當(dāng)一個(gè)組件被從DOM中移除時(shí),該方法被調(diào)用:

- componentWillUnmount()

當(dāng)項(xiàng)目視圖交互復(fù)雜且頻繁的時(shí)候,依舊采用 state 進(jìn)行狀態(tài)更改會(huì)顯得異常繁瑣和不可預(yù)測(cè)。
這時(shí)我們就需要借助 Redux 框架,將狀態(tài)數(shù)據(jù)全部轉(zhuǎn)交給 Redux 處理,React 專一負(fù)責(zé)視圖顯示,這樣會(huì)讓項(xiàng)目邏輯變得簡(jiǎn)單而清晰。

Redux相關(guān)

三大原則:

整個(gè)應(yīng)用的 state 被儲(chǔ)存在一棵 object tree 中,并且這個(gè) object tree 只存在于唯一一個(gè)store中。

惟一改變 state 的方法就是觸發(fā)action,action 是一個(gè)用于描述事件的普通對(duì)象。

為了描述 action 如何改變 state tree ,你需要編寫reducers。

Action

Action 是把數(shù)據(jù)從項(xiàng)目傳到 store 的有效載荷。它是 store 數(shù)據(jù)的唯一來源。通常你會(huì)通過store.dispatch()將 action 傳到 store。

Action 本質(zhì)上是 JavaScript 普通對(duì)象,添加新 todo 任務(wù)的 action 是這樣的:

{
  type: "ADD_TODO",
  text: "Build my first Redux app"
}

Action 創(chuàng)建函數(shù)就是生成 action 的方法。在 Redux 中的 action 創(chuàng)建函數(shù)只是簡(jiǎn)單的返回一個(gè) action:

function addTodo(text) {
  return {
    type: "ADD_TODO",
    text: text
  }
}

這樣做將使 action 創(chuàng)建函數(shù)更容易被移植和測(cè)試。只需把 action 創(chuàng)建函數(shù)的結(jié)果傳給 dispatch() 方法即可發(fā)起一次 dispatch 過程。

dispatch(addTodo(text));

//或者創(chuàng)建一個(gè) 被綁定的 action 創(chuàng)建函數(shù) 來自動(dòng) dispatch:
const boundAddTodo = (text) => dispatch(addTodo(text));
boundAddTodo(text);

store 里能直接通過 store.dispatch() 調(diào)用 dispatch() 方法,但是多數(shù)情況下你會(huì)使用 react-redux 提供的connect()幫助器來調(diào)用。

Reducer

Action 只是描述了有事情發(fā)生了這一事實(shí),而reducer要做的事情正是指明應(yīng)用如何更新 state 。reducer 就是一個(gè)純函數(shù),接收舊的 state 和 action,返回新的 state。

(previousState, action) => newState

保持 reducer 純凈非常重要。永遠(yuǎn)不要在 reducer 里做這些操作:

修改傳入?yún)?shù);

執(zhí)行有副作用的操作,如 API 請(qǐng)求和路由跳轉(zhuǎn);

調(diào)用非純函數(shù),如 Date.now() 或 Math.random()。

我們將以指定 state 的初始狀態(tài)作為開始。Redux 首次執(zhí)行時(shí),state 為 undefined,此時(shí)我們可借機(jī)設(shè)置并返回應(yīng)用的初始 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
  }
}

每個(gè) reducer 只負(fù)責(zé)管理全局 state 中它負(fù)責(zé)的一部分。每個(gè) reducer 的 state 參數(shù)都不同,分別對(duì)應(yīng)它管理的那部分 state 數(shù)據(jù)。

combineReducers()所做的只是生成一個(gè)函數(shù),這個(gè)函數(shù)來調(diào)用你的一系列 reducer,每個(gè) reducer 根據(jù)它們的 key 來篩選出 state 中的一部分?jǐn)?shù)據(jù)并處理,然后這個(gè)生成的函數(shù)再將所有 reducer 的結(jié)果合并成一個(gè)大的對(duì)象。

import { combineReducers } from "redux";

const todoApp = combineReducers({
  visibilityFilter,
  todos
})

export default todoApp;

注意上面的寫法和下面完全等價(jià):

export default function todoApp(state = {}, action) {
  return {
    visibilityFilter: visibilityFilter(state.visibilityFilter, action),
    todos: todos(state.todos, action)
  }
}

combineReducers 接收一個(gè)對(duì)象,可以把所有頂級(jí)的 reducer 放到一個(gè)獨(dú)立的文件中,通過 export 暴露出每個(gè) reducer 函數(shù),然后使用 import * as reducers 得到一個(gè)以它們名字作為 key 的 object:

import { combineReducers } from "redux"
import * as reducers from "./reducers"

const todoApp = combineReducers(reducers)
Store

action 描述發(fā)生了什么,reducers 根據(jù) action 更新 state,Store就是把它們聯(lián)系到一起的對(duì)象。Store 有以下職責(zé):

維持應(yīng)用的 state;

提供getState()方法獲取 state;

提供dispatch(action)方法更新state;

通過subscribe(listener)注冊(cè)監(jiān)聽器;

通過subscribe(listener)返回的函數(shù)注銷監(jiān)聽器。

我們使用 combineReducers() 將多個(gè) reducer 合并成為一個(gè)。現(xiàn)在我們將其導(dǎo)入,并傳遞 createStore()

import { createStore } from "redux"
import todoApp from "./reducers"
let store = createStore(todoApp)

createStore() 的第二個(gè)參數(shù)是可選的, 用于設(shè)置 state 初始狀態(tài)。這對(duì)開發(fā)同構(gòu)應(yīng)用時(shí)非常有用,服務(wù)器端 redux 應(yīng)用的 state 結(jié)構(gòu)可以與客戶端保持一致, 那么客戶端可以將從網(wǎng)絡(luò)接收到的服務(wù)端 state 直接用于本地?cái)?shù)據(jù)初始化。

let store = createStore(todoApp, window.STATE_FROM_SERVER);
數(shù)據(jù)流

Redux 應(yīng)用中數(shù)據(jù)的生命周期遵循下面 4 個(gè)步驟:

調(diào)用 store.dispatch(action)。

Redux store 調(diào)用傳入的 reducer 函數(shù)。

根 reducer 應(yīng)該把多個(gè)子 reducer 輸出合并成一個(gè)單一的 state 樹。

Redux store 保存了根 reducer 返回的完整 state 樹。

Router相關(guān)

直接使用整合后的react-router-redux,后面抽時(shí)間再詳細(xì)講一下,具體使用的話模仿官方案例吧,官方文檔。

容器組件 和 展示組件

Redux 的 React 綁定庫(kù)包含了 容器組件和展示組件相分離 的開發(fā)思想。

明智的做法是只在最頂層組件(如路由操作)里使用 Redux。其余內(nèi)部組件僅僅是展示性的,所有數(shù)據(jù)都通過 props 傳入。

系列目錄

前端大統(tǒng)一時(shí)代即將來臨?

React項(xiàng)目實(shí)戰(zhàn):環(huán)境搭建

React項(xiàng)目實(shí)戰(zhàn):react-redux-router基本原理

React項(xiàng)目實(shí)戰(zhàn):登錄頁面(編輯中)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/54432.html

相關(guān)文章

  • React項(xiàng)目實(shí)戰(zhàn)react-redux-router基本原理

    摘要:組件將元素作為結(jié)果返回。是把數(shù)據(jù)從項(xiàng)目傳到的有效載荷。有以下職責(zé)維持應(yīng)用的提供方法獲取提供方法更新通過注冊(cè)監(jiān)聽器通過返回的函數(shù)注銷監(jiān)聽器。系列目錄前端大統(tǒng)一時(shí)代即將來臨項(xiàng)目實(shí)戰(zhàn)環(huán)境搭建項(xiàng)目實(shí)戰(zhàn)基本原理項(xiàng)目實(shí)戰(zhàn)登錄頁面編輯中 React相關(guān) React 是一個(gè)采用聲明式,高效而且靈活的用來構(gòu)建用戶界面的框架。 JSX 本質(zhì)上來講,JSX 只是為React.createElement(co...

    Doyle 評(píng)論0 收藏0
  • React項(xiàng)目實(shí)戰(zhàn):環(huán)境搭建

    摘要:官方文檔中文翻譯構(gòu)建用戶界面的庫(kù)。官方文檔建議學(xué)習(xí)時(shí)以官方文檔為準(zhǔn),中文翻譯或者第三方作者的教程可以幫助你理清思路會(huì)用到的重要知識(shí)點(diǎn)我也會(huì)進(jìn)行簡(jiǎn)明的解釋,如遇到錯(cuò)誤或者不理解的內(nèi)容,歡迎實(shí)時(shí)指出。 前言 前面提到前端大統(tǒng)一的概念,如果感興趣,歡迎說說自己的看法,點(diǎn)擊前往。Web前端框架層出不窮,不可能面面俱到,這里給個(gè)小建議: 如果對(duì)Weex App感興趣,應(yīng)該選擇vue框架; 如果...

    cnio 評(píng)論0 收藏0
  • React項(xiàng)目實(shí)戰(zhàn):環(huán)境搭建

    摘要:官方文檔中文翻譯構(gòu)建用戶界面的庫(kù)。官方文檔建議學(xué)習(xí)時(shí)以官方文檔為準(zhǔn),中文翻譯或者第三方作者的教程可以幫助你理清思路會(huì)用到的重要知識(shí)點(diǎn)我也會(huì)進(jìn)行簡(jiǎn)明的解釋,如遇到錯(cuò)誤或者不理解的內(nèi)容,歡迎實(shí)時(shí)指出。 前言 前面提到前端大統(tǒng)一的概念,如果感興趣,歡迎說說自己的看法,點(diǎn)擊前往。Web前端框架層出不窮,不可能面面俱到,這里給個(gè)小建議: 如果對(duì)Weex App感興趣,應(yīng)該選擇vue框架; 如果...

    GHOST_349178 評(píng)論0 收藏0
  • react-redux-router4-webpack2組成的大眾點(diǎn)評(píng)的demo.

    該demo使用的是webpack2.*來配置的,很多配置項(xiàng)都產(chǎn)生了變化,踩了不少坑.目前還在逐步完善中,webpack是一部一部配置來的。后端數(shù)據(jù)使用nodejs來開發(fā)模擬。GitHub項(xiàng)目地址。 showImg(https://segmentfault.com/img/remote/1460000009665620); 歡迎大家提問題。

    Caizhenhao 評(píng)論0 收藏0
  • 基于Dva.js的Blog SPA實(shí)踐

    摘要:項(xiàng)目地址項(xiàng)目預(yù)覽登錄流負(fù)責(zé)全局的登錄狀態(tài)管理。總體思想所有的組件都盡量是所有的狀態(tài)組件一般都是路由組件。所有的分發(fā)都交給了路由組件來完成。數(shù)據(jù)的獲取有兩種方式。一種是官方推薦的使用在訂閱數(shù)據(jù)源。 項(xiàng)目地址 https://github.com/HeskeyBaoz... 項(xiàng)目預(yù)覽 showImg(https://segmentfault.com/img/bVIQHX?w=1249&h=...

    vslam 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<