最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

react自定義實(shí)現(xiàn)狀態(tài)管理詳解

 更新時(shí)間:2024年01月15日 14:37:53   作者:不努力code  
這篇文章主要為大家詳細(xì)介紹了react如何自定義實(shí)現(xiàn)狀態(tài)管理,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

redux基礎(chǔ)實(shí)現(xiàn)

myRedux

export const createStore = (reduce) => {
  if (typeof reduce !== 'function') throw new Error('Expected the reducer to be a function.')
  let state,
    listeners = []
  state = reduce()
 
 
  const getState = () => state
  const dispatch = (action) => {
    if(typeof action !== 'object' || typeof action.type !== 'string') throw new Error('Actions must be plain objects.')
    state = reduce(state, action)
    listeners.forEach(listener => listener())
  }
  const subscribe = (listener) => {
    if(typeof listener !== 'function') throw new Error('Expected the listener to be a function.')
    listeners.push(listener)
    return () => listeners = listeners.filter(l => l !== listener)
  }
 
  return {
    getState,
    dispatch,
    subscribe,
  }
}

使用

import React, { useEffect, useState } from 'react'
import { createStore } from './myRedux'
 
 
const reduce = (state = { a: 123 }, action = {}) => {
  state = { ...state }
  switch (action.type) {
    case 'tset':
      state.a = Math.random() * 1000
      return state
    default:
      return state
  }
 
}
const store = createStore(reduce)
 
 
 
export default function Test() {
  const state = store.getState()
  const [_, foceUpdate] = useState(0)
  useEffect(() => {
    store.subscribe(() => {
      foceUpdate(Date.now())
    })
  }, [])
  const change = () => {
    store.dispatch({ type: 'tset' })
  }
  return (
    <div>
      <h1>Test {state.a}</h1>
      <button onClick={change} >change</button>
    </div>
  )
}

react-redux

和源碼可能不同,我沒(méi)看過(guò)源碼,只是實(shí)現(xiàn)一下

react-redux.js

import { useContext, useEffect, useState, createContext } from 'react'
const StoreContext = createContext()
export const Provider = (props) => {
  const store = props.store
  return <StoreContext.Provider value={{ store }}>{props.children}</StoreContext.Provider>
}
 
export const connect = (mapState, mapDispatch) => {
  if (typeof mapState !== 'function') throw new Error('mapState must be an function')
  if (typeof mapDispatch !== 'function') throw new Error('mapDispatch must be an function')
  return (Cpn) => {
    return (props = {}) => {
      const contents = useContext(StoreContext)
      const store = contents.store
      const state = mapState(store.getState())
      const dispatch = mapDispatch(store.dispatch)
      const [_, forceUpdate] = useState(true)
      useEffect(() => {
        store.subscribe(() => {
          forceUpdate(Symbol())
        })
      }, [])
      props = { ...props, ...state, ...dispatch }
      return <Cpn {...props} />
    }
  }
}

使用

import React from 'react'
import { Provider, connect } from './react-redux'
import { createStore } from 'redux'
const reducer = (state = { name: 'test' }, action) => {
  switch (action.type) {
    case 'CHANGE_NAME':
      return { ...state, name: action.name }
    default:
      return state
  }
}
const store = createStore(reducer)
 
function Test2(props) {
  const change = () => {
    props.changeName('test' + Math.random())
  }
  return (
    <div>
      <h1>Test {props.name} </h1>
      <button onClick={change} >change</button>
    </div>
  )
}
const Test3 = connect(
  state => ({ name: state.name }),
  dispatch => ({ changeName: (name) => dispatch({ type: "CHANGE_NAME", name }) })
)(Test2)
 
export default function Test() {
  return (
    <Provider store={store} >
      <Test3 />
    </Provider>
  )
}

模仿pinia方式管理

myPinia.js

export const createStore = (f) => {
  if (typeof f !== 'function') throw new Error('Expected a function')
  const state = f()
  watch(state)
  const proxy = new Proxy(state, {
    get: (target, prop) => {
      const v = target[prop]
      const isState = v instanceof StoreState
      return isState ? v.value : v
    },
    set: () => state,
  })
  const userStore = () => {
    return proxy
  }
 
  return userStore
}
 
const watch = (obj) => {
  Object.keys(obj).forEach((key) => {
    const storeState = obj[key]
    if (storeState instanceof StoreState) {
      let value = storeState.value
      Object.defineProperty(storeState, 'value', {
        get: () => value,
        set: (newValue) => {
          value = newValue
          updateView()
        },
      })
    }
  })
}
 
class StoreState {
  constructor(value) {
    this.value = value
  }
}
 
export const useStoreState = (value) => {
  return new StoreState(value)
}
let listeners = []
const updateView = () => listeners.forEach((f) => f())
export const subscribe = (f) => {
  if (typeof f !== 'function') throw new Error('Expected a function')
  if (!listeners.includes(f)) listeners.push(f)
  return () => (listeners = listeners.filter((l) => l !== f))
}

使用

import React, { useEffect, useState } from 'react'
import { createStore, useStoreState, subscribe } from './myPinia'
 
const userStore = createStore(() => {
  let a = useStoreState(123)
  const change = () => {
    a.value++
  }
  return { a, change }
})
 
export default function Test() {
  const [_, forceUpdate] = useState(0)
  useEffect(() => {
    subscribe(() => forceUpdate(Date.now()))
  }, [])
  const store = userStore()
  const change = () => {
    store.change()
    console.log(store.a);
  }
  return (
    <div>
      <h1>test {store.a}</h1>
      <button onClick={change} >change</button>
    </div>
  )
}

不足的是,還是需要forceUpdate

以上就是react自定義實(shí)現(xiàn)狀態(tài)管理詳解的詳細(xì)內(nèi)容,更多關(guān)于react狀態(tài)管理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談React底層實(shí)現(xiàn)原理

    淺談React底層實(shí)現(xiàn)原理

    本文主要介紹了淺談React底層實(shí)現(xiàn)原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • react中使用useEffect及踩坑記錄

    react中使用useEffect及踩坑記錄

    這篇文章主要介紹了react中使用useEffect及踩坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • React 的 getDefaultProps簡(jiǎn)介、用法與最佳實(shí)踐方案

    React 的 getDefaultProps簡(jiǎn)介、用法與最佳實(shí)踐方案

    React組件通過(guò)getDefaultProps設(shè)置默認(rèn)屬性,防止未傳props導(dǎo)致的錯(cuò)誤,隨著React發(fā)展,方式從方法演變?yōu)閟tatic defaultProps及函數(shù)參數(shù)默認(rèn)值,建議根據(jù)項(xiàng)目選擇合適語(yǔ)法,本文給大家介紹React 的 getDefaultProps簡(jiǎn)介、用法與最佳實(shí)踐方案,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • React Native中ScrollView組件輪播圖與ListView渲染列表組件用法實(shí)例分析

    React Native中ScrollView組件輪播圖與ListView渲染列表組件用法實(shí)例分析

    這篇文章主要介紹了React Native中ScrollView組件輪播圖與ListView渲染列表組件用法,結(jié)合實(shí)例形式詳細(xì)分析了ScrollView組件輪播圖與ListView渲染列表組件具體功能、使用方法與操作注意事項(xiàng),需要的朋友可以參考下
    2020-01-01
  • react組件中的constructor和super知識(shí)點(diǎn)整理

    react組件中的constructor和super知識(shí)點(diǎn)整理

    這篇文章主要介紹了react組件中的constructor和super知識(shí)點(diǎn)整理,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • React項(xiàng)目中實(shí)現(xiàn)數(shù)據(jù)持久化的方法大全

    React項(xiàng)目中實(shí)現(xiàn)數(shù)據(jù)持久化的方法大全

    在React應(yīng)用開(kāi)發(fā)中,數(shù)據(jù)持久化是一個(gè)至關(guān)重要的需求,當(dāng)用戶(hù)刷新頁(yè)面、關(guān)閉瀏覽器后重新打開(kāi)應(yīng)用,或者在不同設(shè)備間切換時(shí),我們希望能夠保持用戶(hù)的數(shù)據(jù)狀態(tài),本文將全面介紹React項(xiàng)目中實(shí)現(xiàn)數(shù)據(jù)持久化的各種方法,需要的朋友可以參考下
    2025-09-09
  • react如何使用useRef模仿抖音標(biāo)題里面添加標(biāo)簽內(nèi)容

    react如何使用useRef模仿抖音標(biāo)題里面添加標(biāo)簽內(nèi)容

    本文介紹了如何模仿抖音發(fā)布頁(yè)面,使用div元素作為輸入框,并利用CSS樣式和JavaScript動(dòng)態(tài)操作DOM,實(shí)現(xiàn)類(lèi)似于input輸入框的功能,感興趣的朋友跟隨小編一起看看吧
    2024-10-10
  • react-navigation 如何判斷用戶(hù)是否登錄跳轉(zhuǎn)到登錄頁(yè)的方法

    react-navigation 如何判斷用戶(hù)是否登錄跳轉(zhuǎn)到登錄頁(yè)的方法

    本篇文章主要介紹了react-navigation 如何判斷用戶(hù)是否登錄跳轉(zhuǎn)到登錄頁(yè)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • 在React中應(yīng)用SOLID原則的方法

    在React中應(yīng)用SOLID原則的方法

    SOLID?是一套原則,它們主要是關(guān)心代碼質(zhì)量和可維護(hù)性的軟件專(zhuān)業(yè)人員的指導(dǎo)方針,本文給大家分享如何在React中應(yīng)用SOLID原則,感興趣的朋友一起看看吧
    2022-07-07
  • 使用store來(lái)優(yōu)化React組件的方法

    使用store來(lái)優(yōu)化React組件的方法

    這篇文章主要介紹了使用store來(lái)優(yōu)化React組件的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10

最新評(píng)論

报价| 西平县| 桦甸市| 哈巴河县| 镇平县| 德昌县| 兴城市| 桑日县| 肥乡县| 阿合奇县| 普洱| 基隆市| 武邑县| 桓台县| 泌阳县| 盐亭县| 五指山市| 久治县| 兴仁县| 普定县| 西安市| 宝应县| 荆门市| 乐山市| 平泉县| 呼图壁县| 仙桃市| 乐平市| 武宣县| 遵化市| 华池县| 赤水市| 昔阳县| 南靖县| 公安县| 景泰县| 乌什县| 富民县| 兰溪市| 溧阳市| 新巴尔虎左旗|