国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

實現(xiàn)React-redux的基本功能

dreamans / 2153人閱讀

摘要:要實現(xiàn)先搞清楚的就是這么一個東西,某個組件只要往自己的里面放了某些狀態(tài),這個組件之下的所有子組件都直接訪問這個狀態(tài)而不需要通過中間組件的傳遞。

1.要實現(xiàn)redux,先搞清楚context
React.js 的 context 就是這么一個東西,某個組件只要往自己的 context 里面放了某些狀態(tài),這個組件之下的所有子組件都直接訪問這個狀態(tài)而不需要通過中間組件的傳遞。一個組件的 context 只有它的子組件能夠訪問,它的父組件是不能訪問到的
//現(xiàn)在我們修改 Index,讓它往自己的 context 里面放一個 themeColor
class Index extends Component {
  static childContextTypes = {//要給組件設(shè)置 context,那么 childContextTypes 是必寫的
    themeColor: PropTypes.string
  }

  constructor () {
    super()
    this.state = { themeColor: "red" }
  }

  getChildContext () {
    return { themeColor: this.state.themeColor }
  }

  render () {
    return (
      
) } }
//子組件直接獲取context里面的東西
//子組件要獲取 context 里面的內(nèi)容的話,就必須寫 contextTypes 來聲明和驗證你需要獲取的狀態(tài)的類型,
//它也是必寫的
class Title extends Component {
  static contextTypes = {
    themeColor: PropTypes.string
  }

  render () {
    return (
      

React.js

) } }
2.實現(xiàn)共享狀態(tài)優(yōu)化
context 打破了組件和組件之間通過 props 傳遞數(shù)據(jù)的規(guī)范,極大地增強了組件之間的耦合性。而且,就如全局變量一樣,context 里面的數(shù)據(jù)能被隨意接觸就能被隨意修改,每個組件都能夠改 context 里面的內(nèi)容會導(dǎo)致程序的運行不可預(yù)料,這時我們就需要規(guī)范對共享狀態(tài)的修改

1.假設(shè)使用的是一個共享狀態(tài) appState,每個人都可以修改它
2.所有對共享狀態(tài)的操作都是不可預(yù)料的(某個模塊 appState.title = null 你一點意見都沒有),出現(xiàn)問題的時候 debug 起來就非常困難
3.如果所有對數(shù)據(jù)的操作必須通過 dispatch 函數(shù)。它接受一個參數(shù) action,這個 action 是一個普通的 JavaScript 對象,里面必須包含一個 type 字段來聲明你到底想干什么,那就好操作了

4.我們可以把appState 和 dispatch抽離出來結(jié)合到一起形成store,構(gòu)建一個函數(shù) createStore,用來專門生產(chǎn)這種 state 和 dispatch 的集合

/*createStore 接受兩個參數(shù),一個是表示應(yīng)用程序狀態(tài)的 state;另外一個是 stateChanger,
它來描述應(yīng)用程序狀態(tài)會根據(jù) action 發(fā)生什么變化*/
function createStore (state, stateChanger) {
  const getState = () => state
  const dispatch = (action) => stateChanger(state, action)
  return { getState, dispatch }
}
renderApp(store.getState()) // 首次渲染頁面
store.dispatch({ type: "UPDATE_TITLE_TEXT", text: "《React.js 》" }) // 修改標(biāo)題文本
store.dispatch({ type: "UPDATE_TITLE_COLOR", color: "blue" }) // 修改標(biāo)題顏色
renderApp(store.getState()) // 把新的數(shù)據(jù)渲染到頁面上
3.實現(xiàn)Redux數(shù)據(jù)刷新優(yōu)化

1.細上面代碼中更改數(shù)據(jù)后需要手動調(diào)用renderapp刷新,這里我們可以用觀察者模式優(yōu)化刷新

function createStore (state, stateChanger) {
  const listeners = []
  const subscribe = (listener) => listeners.push(listener)
  const getState = () => state
  const dispatch = (action) => {
    stateChanger(state, action)
    listeners.forEach((listener) => listener())//dispatch后調(diào)用我傳入subscribe的刷新方式
  }
  return { getState, dispatch, subscribe }
}
//可以用同一個APPstate去渲染不同的頁面
const store = createStore(appState, stateChanger)
store.subscribe(() => renderApp(store.getState()))
store.subscribe(() => renderApp2(store.getState()))
store.subscribe(() => renderApp3(store.getState()))

2.避免重復(fù)渲染優(yōu)化 這里直接引用胡子大叔的優(yōu)化

function createStore (state, stateChanger) {
  const listeners = []
  const subscribe = (listener) => listeners.push(listener)
  const getState = () => state
  const dispatch = (action) => {
    state = stateChanger(state, action) // 覆蓋原對象
    listeners.forEach((listener) => listener())
  }
  return { getState, dispatch, subscribe }
}

function renderApp (newAppState, oldAppState = {}) { // 防止 oldAppState 沒有傳入,所以加了默認(rèn)參數(shù) oldAppState = {}
  if (newAppState === oldAppState) return // 數(shù)據(jù)沒有變化就不渲染了
  console.log("render app...")
  renderTitle(newAppState.title, oldAppState.title)
  renderContent(newAppState.content, oldAppState.content)
}

function renderTitle (newTitle, oldTitle = {}) {
  if (newTitle === oldTitle) return // 數(shù)據(jù)沒有變化就不渲染了
  console.log("render title...")
  const titleDOM = document.getElementById("title")
  titleDOM.innerHTML = newTitle.text
  titleDOM.style.color = newTitle.color
}

function renderContent (newContent, oldContent = {}) {
  if (newContent === oldContent) return // 數(shù)據(jù)沒有變化就不渲染了
  console.log("render content...")
  const contentDOM = document.getElementById("content")
  contentDOM.innerHTML = newContent.text
  contentDOM.style.color = newContent.color
}

let appState = {
  title: {
    text: "React.js 小書",
    color: "red",
  },
  content: {
    text: "React.js 小書內(nèi)容",
    color: "blue"
  }
}

function stateChanger (state, action) {
  switch (action.type) {
    case "UPDATE_TITLE_TEXT":
      return { // 構(gòu)建新的對象并且返回
        ...state,
        title: {
          ...state.title,
          text: action.text
        }
      }
    case "UPDATE_TITLE_COLOR":
      return { // 構(gòu)建新的對象并且返回
        ...state,
        title: {
          ...state.title,
          color: action.color
        }
      }
    default:
      return state // 沒有修改,返回原來的對象
  }
}

const store = createStore(appState, stateChanger)
let oldState = store.getState() // 緩存舊的 state
store.subscribe(() => {
  const newState = store.getState() // 數(shù)據(jù)可能變化,獲取新的 state
  renderApp(newState, oldState) // 把新舊的 state 傳進去渲染
  oldState = newState // 渲染完以后,新的 newState 變成了舊的 oldState,等待下一次數(shù)據(jù)變化重新渲染
})

renderApp(store.getState()) // 首次渲染頁面
store.dispatch({ type: "UPDATE_TITLE_TEXT", text: "《React.js 小書》" }) // 修改標(biāo)題文本
store.dispatch({ type: "UPDATE_TITLE_COLOR", color: "blue" }) // 修改標(biāo)題顏色
4.Reducer
其實 appState 和 stateChanger 可以合并到一起去

1將appstate放入statechanger

function stateChanger (state, action) {
  if (!state) {
    return {
      title: {
        text: "React.js 小書",
        color: "red",
      },
      content: {
        text: "React.js 小書內(nèi)容",
        color: "blue"
      }
    }
  }
  switch (action.type) {
    case "UPDATE_TITLE_TEXT":
      return {
        ...state,
        title: {
          ...state.title,
          text: action.text
        }
      }
    case "UPDATE_TITLE_COLOR":
      return {
        ...state,
        title: {
          ...state.title,
          color: action.color
        }
      }
    default:
      return state
  }
}

2.creactstore的參數(shù)就會被優(yōu)化為一個

function createStore (stateChanger) {
  let state = null
  const listeners = []
  const subscribe = (listener) => listeners.push(listener)
  const getState = () => state
  const dispatch = (action) => {
    state = stateChanger(state, action)
    listeners.forEach((listener) => listener())
  }
  dispatch({}) // 初始化 state
  return { getState, dispatch, subscribe }
}

3.最后我們規(guī)定createStore參數(shù)的名字為reducer,且reducer是一個純函數(shù)

reducer 是不允許有副作用的。你不能在里面操作 DOM,也不能發(fā) Ajax 請求,更不能直接修改 state,它要做的僅僅是 —— 初始化和計算新的 state
// 定一個 reducer
function reducer (state, action) {
  /* 初始化 state 和 switch case */
}
// 生成 store
const store = createStore(reducer)
// 監(jiān)聽數(shù)據(jù)變化重新渲染頁面
store.subscribe(() => renderApp(store.getState()))
// 首次渲染頁面
renderApp(store.getState()) 
// 后面可以隨意 dispatch 了,頁面自動更新
store.dispatch(...)
5.React-redux中的store和context
React.js 的 context 中提出,我們可用把共享狀態(tài)放到父組件的 context 上,這個父組件下所有的組件都可以從 context 中直接獲取到狀態(tài)而不需要一層層地進行傳遞了,但組件對其的改動會讓context不可預(yù)料。 store 的數(shù)據(jù)不是誰都能修改,而是約定只能通過 dispatch 來進行修改,這樣的話每個組件既可以去 context 里面獲取 store 從而獲取狀態(tài),又不用擔(dān)心它們亂改數(shù)據(jù)了,所以將store和context結(jié)合起來

1.構(gòu)建自己的React-redux

import React, { Component } from "react"
import PropTypes from "prop-types"
import ReactDOM from "react-dom"
import Header from "./Header"
import Content from "./Content"
import "./index.css"

function createStore (reducer) {
  let state = null
  const listeners = [
  const subscribe = (listener) => listeners.push(listener)
  const getState = () => state//這是函數(shù)表達式 調(diào)用它時state已經(jīng)初始化了
  const dispatch = (action) => {
    state = reducer(state, action)
    listeners.forEach((listener) => listener())
  }
  dispatch({}) // 初始化 state
  return { getState, dispatch, subscribe }
}

const themeReducer = (state, action) => {
  if (!state) return {
    themeColor: "red"
  }
  switch (action.type) {
    case "CHANGE_COLOR":
      return { ...state, themeColor: action.themeColor }
    default:
      return state
  }
}

const store = createStore(themeReducer)

class Index extends Component {
  static childContextTypes = {
    store: PropTypes.object
  }

  getChildContext () {
    return { store }//將store放入context
  }

  render () {
    return (
      
) } }

2.子組件獲取context中的配置

class Header extends Component {
  static contextTypes = {
    store: PropTypes.object
  }

  constructor () {
    super()
    this.state = { themeColor: "" }
  }

  componentWillMount () {
    this._updateThemeColor()
  }

  _updateThemeColor () {
    const { store } = this.context//解構(gòu)賦值取出來
    const state = store.getState()
    this.setState({ themeColor: state.themeColor })//放到state中來用
  }

  render () {
    return (
      

React.js 小書

) } }

3.用dispatch去改變配置刷新頁面

//首先配置監(jiān)聽函數(shù)的刷新模式
componentWillMount () {
    const { store } = this.context
    this._updateThemeColor()//獲取默認(rèn)數(shù)據(jù)加載
    store.subscribe(() => this._updateThemeColor())//dispatch數(shù)據(jù)更改后加載
  }
//觸發(fā)事件
  handleSwitchColor (color) {
    const { store } = this.context
    store.dispatch({
      type: "CHANGE_COLOR",
      themeColor: color
    })
  }
6.React-redux與組件拆分開,讓組件無污染可復(fù)用性強
可以把一些可復(fù)用的邏輯放在高階組件當(dāng)中,高階組件包裝的新組件和原來組件之間通過 props 傳遞信息,減少代碼的重復(fù)程度,我們需要高階組件幫助我們從 context 取數(shù)據(jù),然后用高階組件把它們包裝一層,高階組件和 context 打交道,把里面數(shù)據(jù)取出來通過 props 傳給 Dumb 組件

1.這個高階組件起名字叫 connect,因為它把 Dumb 組件和 context 連接
2.每個傳進去的組件需要 store 里面的數(shù)據(jù)都不一樣的,所以除了給高階組件傳入 Dumb 組件以外,還需要告訴高級組件我們需要什么數(shù)據(jù)

import React, { Component } from "react"
import PropTypes from "prop-types"
//connect 現(xiàn)在是接受一個參數(shù) mapStateToProps,然后返回一個函數(shù),這個返回的函數(shù)才是高階組件
export const connect = (mapStateToProps) => (WrappedComponent) => {
  class Connect extends Component {
    static contextTypes = {
      store: PropTypes.object
    }

    render () {
      const { store } = this.context
      let stateProps = mapStateToProps(store.getState())
      // {...stateProps} 意思是把這個對象里面的屬性全部通過 `props` 方式傳遞進去
      return 
    }
  }

  return Connect
}

----------
//mapStateToProps為傳入數(shù)據(jù)的方式
const mapStateToProps = (state) => {
  return {
    themeColor: state.themeColor
  }
}
Header = connect(mapStateToProps)(Header)
//這里的mapStateToprops在connect里面執(zhí)行并把獲取的數(shù)據(jù)放到header的props中

3.除了傳遞數(shù)據(jù)我們還需要高階組件來 dispatch

const mapDispatchToProps = (dispatch) => {
  return {
    onSwitchColor: (color) => {
      dispatch({ type: "CHANGE_COLOR", themeColor: color })
    }
  }
}

4.結(jié)合起來構(gòu)建Connect

export const connect = (mapStateToProps, mapDispatchToProps) => (WrappedComponent) => {
  class Connect extends Component {
    static contextTypes = {
      store: PropTypes.object
    }

    constructor () {
      super()
      this.state = {
        allProps: {}
      }
    }

    componentWillMount () {
      const { store } = this.context
      this._updateProps()
      store.subscribe(() => this._updateProps())
    }

    _updateProps () {
      const { store } = this.context
      let stateProps = mapStateToProps
        ? mapStateToProps(store.getState(), this.props)
        : {} // 防止 mapStateToProps 沒有傳入
      let dispatchProps = mapDispatchToProps
        ? mapDispatchToProps(store.dispatch, this.props)
        : {} // 防止 mapDispatchToProps 沒有傳入
      this.setState({
        allProps: {
          ...stateProps,
          ...dispatchProps,
          ...this.props
        }
      })
    }

    render () {
      return 
    }
  }
  return Connect
}

5.剝離出index.js

class Index extends Component {
  static childContextTypes = {
    store: PropTypes.object
  }

  getChildContext () {
    return { store }
  }//這些都是污染需要剝離

  render () {
    return (
      
) } }

6.Provider

//將index中污染部分放入Provider,再用成為index的父組件
export class Provider extends Component {
  static propTypes = {
    store: PropTypes.object,
    children: PropTypes.any
  }

  static childContextTypes = {
    store: PropTypes.object
  }

  getChildContext () {
    return {
      store: this.props.store
    }
  }

  render () {
    return (
      
{this.props.children}
) } }
...
// 頭部引入 Provider
import { Provider } from "./react-redux"
...

// 刪除 Index 里面所有關(guān)于 context 的代碼
class Index extends Component {
  render () {
    return (
      
) } } // 把 Provider 作為組件樹的根節(jié)點 ReactDOM.render( , document.getElementById("root") )

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/108899.html

相關(guān)文章

  • redux以及react-redux簡單實現(xiàn)

    摘要:寫在前頭簡介隨著單頁應(yīng)用開發(fā)日趨復(fù)雜,需要管理比任何時候都要多的狀態(tài)。如果一個的變化會引起另一個變化,那么當(dāng)變化時,就可能引起對應(yīng)以及另一個的變化,依次地,可能會引起另一個的變化。一些庫如試圖在視圖層禁止異步和直接操作來解決這個問題。 寫在前頭 redux 簡介 ? 隨著 JavaScript 單頁應(yīng)用開發(fā)日趨復(fù)雜,JavaScript 需要管理比任何時候都要多的 state (...

    elliott_hu 評論0 收藏0
  • 實現(xiàn)React-redux基本功能

    摘要:要實現(xiàn)先搞清楚的就是這么一個東西,某個組件只要往自己的里面放了某些狀態(tài),這個組件之下的所有子組件都直接訪問這個狀態(tài)而不需要通過中間組件的傳遞。 1.要實現(xiàn)redux,先搞清楚context React.js 的 context 就是這么一個東西,某個組件只要往自己的 context 里面放了某些狀態(tài),這個組件之下的所有子組件都直接訪問這個狀態(tài)而不需要通過中間組件的傳遞。一個組件的 co...

    dmlllll 評論0 收藏0
  • react-redux初級教程,純白話講述redux數(shù)據(jù)、開發(fā)流程整理,redux數(shù)據(jù)持久化實現(xiàn)

    摘要:日常項目直接使用是完全沒有問題的,可是隨著項目的日益壯大,組件數(shù)量的逐漸增長,組件之間的嵌套使得數(shù)據(jù)的管理越來越繁重。最后數(shù)據(jù)保存進了中的,頁面也會根據(jù)的改變自動更新。 以下文章均為個人近期所學(xué)心得,自學(xué)react、redux,逐漸找到自己的方向,現(xiàn)將自己的方向方式寫出來,以供大家學(xué)習(xí)參考,肯定會有不足,歡迎批評指正。 日常項目直接使用react是完全沒有問題的,可是隨著項目的日益壯大...

    gclove 評論0 收藏0
  • React 實踐心得:react-redux 之 connect 方法詳解

    摘要:但這并不是最佳的方式。最佳的方式是使用提供的和方法。也就是說,與的與完全無關(guān)。另外,如果使用對做屬性類型檢查,方法和方法為添加的屬性是存在的。注意,的變化不會引起上述過程,默認(rèn)在組件的生命周期中是固定的。 轉(zhuǎn)載注: 本文作者是淘寶前端團隊的葉齋。筆者非常喜歡這篇文章,故重新排版并轉(zhuǎn)載到這里,同時也加入了一些自己的體會。 原文地址:http://taobaofed.org/blog/...

    張春雷 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<