欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

ReactHook核心原理是什么

本篇內(nèi)容主要講解“ReactHook核心原理是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“ReactHook核心原理是什么”吧!

我們提供的服務(wù)有:成都做網(wǎng)站、成都網(wǎng)站建設(shè)、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、鹿寨ssl等。為近1000家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的鹿寨網(wǎng)站制作公司

基本準(zhǔn)備工作

  • 手寫useState:useState的使用,原理實(shí)現(xiàn)。

  • React.memo介紹

  • 手寫useCallback:useCallback的使用,原理實(shí)現(xiàn)。

  • 手寫useMemo:使用,原理。

  • 手寫useReducer:使用,原理。

  • 手寫useContext:使用,原理。

  • 手寫useEffect:使用,原理。

  • 手寫useLayoutEffect:使用,原理。

基本準(zhǔn)備工作

利用 creact-react-app 創(chuàng)建一個項目

ReactHook核心原理是什么

已經(jīng)把項目放到 github:https://github.com/Sunny-lucking/HowToBuildMyReactHook  可以卑微地要個star嗎

手寫useState

useState的使用

useState可以在函數(shù)組件中,添加state Hook。

調(diào)用useState會返回一個state變量,以及更新state變量的方法。useState的參數(shù)是state變量的初始值,初始值僅在初次渲染時有效。

更新state變量的方法,并不會像this.setState一樣,合并state。而是替換state變量。下面是一個簡單的例子,  會在頁面上渲染count的值,點(diǎn)擊setCount的按鈕會更新count的值。

function App(){     const [count, setCount] = useState(0);     return (         <div>             {count}             <button                 onClick={() => {                     setCount(count + 1);                 }}             >                 增加             </button>         </div>     ); } ReactDOM.render(     <App />,   document.getElementById('root') );

原理實(shí)現(xiàn)

let lastState function useState(initState) {     lastState = lastState || initState;     function setState(newState) {         lastState = newState     }     return [lastState,setState] } function App(){     //。。。 } ReactDOM.render(     <App />,   document.getElementById('root') );

如代碼所示,我們自己創(chuàng)建了一個useState方法

當(dāng)我們使用這個方法時,如果是第一次使用,則取initState的值,否則就取上一次的值(laststate).

在內(nèi)部,我們創(chuàng)建了一個setState方法,該方法用于更新state的值

然后返回一個lastSate屬性和setState方法。

看似完美,但是我們其實(shí)忽略了一個問題:每次執(zhí)行玩setState都應(yīng)該重新渲染當(dāng)前組件的。

所以我們需要在setState里面執(zhí)行刷新操作

let lastState function useState(initState) {     lastState = lastState || initState;     function setState(newState) {         lastState = newState         render()     }     return [lastState,setState] } function App(){     const [count, setCount] = useState(0);     return (         <div>             {count}             <button                 onClick={() => {                     setCount(count + 1);                 }}             >                 增加             </button>         </div>     ); } // 新增方法 function render(){     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

如代碼所示,我們在setState里添加了個render方法。render方法則會執(zhí)行

ReactDOM.render(         <App />,         document.getElementById('root')     );

也就是重新渲染啦。

好了,現(xiàn)在是不是已經(jīng)完整了呢?

不,還有個問題:就說我們這里只是用了一個useState,要是我們使用了很多個呢?難道要聲明很多個全局變量嗎?

這顯然是不行的,所以,我們可以設(shè)計一個全局?jǐn)?shù)組來保存這些state

let lastState = [] let stateIndex = 0 function useState(initState) {     lastState[stateIndex] = lastState[stateIndex] || initState;     const currentIndex = stateIndex     function setState(newState) {         lastState[stateIndex] = newState         render()     }     return [lastState[stateIndex++],setState] }

這里的currentIndex是利用了閉包的思想,將某個state相應(yīng)的index記錄下來了。

好了,useState方法就到這里基本完成了。是不是so easy!!!

React.memo介紹

看下面的代碼!你發(fā)現(xiàn)什么問題?

import React ,{useState}from 'react'; import ReactDOM from 'react-dom'; import './index.css'; function Child({data}) {     console.log("天啊,我怎么被渲染啦,我并不希望啊")     return (         <div>child</div>     ) } function App(){     const [count, setCount] = useState(0);     return (         <div>             <Child data={123}></Child>             <button onClick={() => { setCount(count + 1)}}>                 增加             </button>         </div>     ); } function render(){     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

沒錯,就是盡管我們傳個子組件的props是固定的值,當(dāng)父組件的數(shù)據(jù)更改時,子組件也被重新渲染了,我們是希望當(dāng)傳給子組件的props改變時,才重新渲染子組件。

所以引入了React.memo。

看看介紹

React.memo() 和 PureComponent 很相似,它幫助我們控制何時重新渲染組件。

組件僅在它的 props 發(fā)生改變的時候進(jìn)行重新渲染。通常來說,在組件樹中 React 組件,只要有變化就會走一遍渲染流程。但是通過  PureComponent 和 React.memo(),我們可以僅僅讓某些組件進(jìn)行渲染。

import React ,{useState,memo}from 'react'; import ReactDOM from 'react-dom'; import './index.css'; function Child({data}) {     console.log("天啊,我怎么被渲染啦,我并不希望啊")     return (         <div>child</div>     ) } Child = memo(Child) function App(){     const [count, setCount] = useState(0);     return (         <div>             <Child data={123}></Child>             <button onClick={() => { setCount(count + 1)}}>                 增加             </button>         </div>     ); } function render(){     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

因此,當(dāng)Child被memo包裝后,就只會當(dāng)props改變時才會重新渲染了。

當(dāng)然,由于React.memo并不是react-hook的內(nèi)容,所以這里并不會取討論它是怎么實(shí)現(xiàn)的。

手寫useCallback

useCallback的使用

當(dāng)我們試圖給一個子組件傳遞一個方法的時候,如下代碼所示

import React ,{useState,memo}from 'react'; import ReactDOM from 'react-dom'; function Child({data}) {     console.log("天啊,我怎么被渲染啦,我并不希望啊")     return (         <div>child</div>     ) } // eslint-disable-next-line Child = memo(Child) function App(){     const [count, setCount] = useState(0);     const addClick = ()=>{console.log("addClick")}     return (         <div>                          <Child data={123} onClick={addClick}></Child>             <button onClick={() => { setCount(count + 1)}}>                 增加             </button>         </div>     ); } function render(){     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

發(fā)現(xiàn)我們傳了一個addClick方法 是固定的,但是卻每一次點(diǎn)擊按鈕子組件都會重新渲染。

這是因?yàn)槟憧此芶ddClick方法沒改變,其實(shí)舊的和新的addClick是不一樣的,如圖所示

ReactHook核心原理是什么

在這里插入圖片描述

這時,如果想要,傳入的都是同一個方法,就要用到useCallBack。

如代碼所示

import React ,{useState,memo,useCallback}from 'react'; import ReactDOM from 'react-dom'; function Child({data}) {     console.log("天啊,我怎么被渲染啦,我并不希望啊")     return (         <div>child</div>     ) } // eslint-disable-next-line Child = memo(Child) function App(){     const [count, setCount] = useState(0);     // eslint-disable-next-line     const addClick = useCallback(()=>{console.log("addClick")},[])     return (         <div>                          <Child data={123} onClick={addClick}></Child>             <button onClick={() => { setCount(count + 1)}}>                 增加             </button>         </div>     ); } function render(){     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

useCallback鉤子的第一個參數(shù)是我們要傳遞給子組件的方法,第二個參數(shù)是一個數(shù)組,用于監(jiān)聽數(shù)組里的元素變化的時候,才會返回一個新的方法。

原理實(shí)現(xiàn)

我們知道useCallback有兩個參數(shù),所以可以先寫

function useCallback(callback,lastCallbackDependencies){           }

跟useState一樣,我們同樣需要用全局變量把callback和dependencies保存下來。

let lastCallback let lastCallbackDependencies function useCallback(callback,dependencies){     }

首先useCallback會判斷我們是否傳入了依賴項,如果沒有傳的話,說明要每一次執(zhí)行useCallback都返回最新的callback

let lastCallback let lastCallbackDependencies function useCallback(callback,dependencies){     if(lastCallbackDependencies){      }else{ // 沒有傳入依賴項               }     return lastCallback }

所以當(dāng)我們沒有傳入依賴項的時候,實(shí)際上可以把它當(dāng)作第一次執(zhí)行,因此,要把lastCallback和lastCallbackDependencies重新賦值

let lastCallback let lastCallbackDependencies function useCallback(callback,dependencies){     if(lastCallbackDependencies){      }else{ // 沒有傳入依賴項                  lastCallback = callback         lastCallbackDependencies = dependencies     }     return lastCallback }

當(dāng)有傳入依賴項的時候,需要看看新的依賴數(shù)組的每一項和來的依賴數(shù)組的每一項的值是否相等

let lastCallback let lastCallbackDependencies function useCallback(callback,dependencies){     if(lastCallbackDependencies){         let changed = !dependencies.every((item,index)=>{             return item === lastCallbackDependencies[index]         })     }else{ // 沒有傳入依賴項                  lastCallback = callback         lastCallbackDependencies = dependencies     }     return lastCallback } function Child({data}) {     console.log("天啊,我怎么被渲染啦,我并不希望啊")     return (         <div>child</div>     ) }

當(dāng)依賴項有值改變的時候,我們需要對lastCallback和lastCallbackDependencies重新賦值

import React ,{useState,memo}from 'react'; import ReactDOM from 'react-dom'; let lastCallback // eslint-disable-next-line let lastCallbackDependencies function useCallback(callback,dependencies){     if(lastCallbackDependencies){         let changed = !dependencies.every((item,index)=>{             return item === lastCallbackDependencies[index]         })         if(changed){             lastCallback = callback             lastCallbackDependencies = dependencies         }     }else{ // 沒有傳入依賴項                  lastCallback = callback         lastCallbackDependencies = dependencies     }     return lastCallback } function Child({data}) {     console.log("天啊,我怎么被渲染啦,我并不希望啊")     return (         <div>child</div>     ) } // eslint-disable-next-line Child = memo(Child) function App(){     const [count, setCount] = useState(0);     // eslint-disable-next-line     const addClick = useCallback(()=>{console.log("addClick")},[])     return (         <div>                          <Child data={123} onClick={addClick}></Child>             <button onClick={() => { setCount(count + 1)}}>                 增加             </button>         </div>     ); } function render(){     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

手寫useMemo

使用

useMemo和useCallback類似,不過useCallback用于緩存函數(shù),而useMemo用于緩存函數(shù)返回值

let data = useMemo(()=> ({number}),[number])

如代碼所示,利用useMemo用于緩存函數(shù)的返回值number,并且當(dāng)只有監(jiān)聽元素為[number],也就是說,當(dāng)number的值發(fā)生改變的時候,才會重新執(zhí)行

()=> ({number})

然后返回新的number

原理

所以,useMemo的原理跟useCallback的差不多,仿寫即可。

import React ,{useState,memo,}from 'react'; import ReactDOM from 'react-dom'; let lastMemo // eslint-disable-next-line let lastMemoDependencies function useMemo(callback,dependencies){     if(lastMemoDependencies){         let changed = !dependencies.every((item,index)=>{             return item === lastMemoDependencies[index]         })         if(changed){             lastMemo = callback()             lastMemoDependencies = dependencies         }     }else{ // 沒有傳入依賴項         lastMemo = callback()         lastMemoDependencies = dependencies     }     return lastMemo } function Child({data}) {     console.log("天啊,我怎么被渲染啦,我并不希望啊")     return (         <div>child</div>     ) } // eslint-disable-next-line Child = memo(Child) function App(){     const [count, setCount] = useState(0);     // eslint-disable-next-line     const [number, setNumber] = useState(20)     let data = useMemo(()=> ({number}),[number])     return (         <div>                          <Child data={data}></Child>             <button onClick={() => { setCount(count + 1)}}>                 增加             </button>         </div>     ); } function render(){     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

手寫useReducer

使用

先簡單介紹下useReducer。

const [state, dispatch] = useReducer(reducer, initState);

useReducer接收兩個參數(shù):

第一個參數(shù):reducer函數(shù),第二個參數(shù):初始化的state。

返回值為最新的state和dispatch函數(shù)(用來觸發(fā)reducer函數(shù),計算對應(yīng)的state)。

按照官方的說法:對于復(fù)雜的state操作邏輯,嵌套的state的對象,推薦使用useReducer。

聽起來比較抽象,我們先看一個簡單的例子:

// 官方 useReducer Demo // 第一個參數(shù):應(yīng)用的初始化 const initialState = {count: 0};  // 第二個參數(shù):state的reducer處理函數(shù) function reducer(state, action) {     switch (action.type) {         case 'increment':           return {count: state.count + 1};         case 'decrement':            return {count: state.count - 1};         default:             throw new Error();     } }  function Counter() {     // 返回值:最新的state和dispatch函數(shù)     const [state, dispatch] = useReducer(reducer, initialState);     return (         <>             // useReducer會根據(jù)dispatch的action,返回最終的state,并觸發(fā)rerender             Count: {state.count}             // dispatch 用來接收一個 action參數(shù)「reducer中的action」,用來觸發(fā)reducer函數(shù),更新最新的狀態(tài)             <button onClick={() => dispatch({type: 'increment'})}>+</button>             <button onClick={() => dispatch({type: 'decrement'})}>-</button>         </>     ); }

其實(shí)意思可以簡單的理解為,當(dāng)state是基本數(shù)據(jù)類型的時候,可以用useState,當(dāng)state是對象的時候,可以用reducer,當(dāng)然這只是一種簡單的想法。大家不必引以為意。具體情況視具體場景分析。

原理

看原理你會發(fā)現(xiàn)十分簡單,簡單到不用我說什么,不到十行代碼,不信你直接看代碼

import React from 'react'; import ReactDOM from 'react-dom';  let lastState // useReducer原理 function useReducer(reducer,initialState){     lastState = lastState || initialState     function dispatch(action){         lastState = reducer(lastState,action)         render()     }     return [lastState,dispatch] }  // 官方 useReducer Demo // 第一個參數(shù):應(yīng)用的初始化 const initialState = {count: 0};  // 第二個參數(shù):state的reducer處理函數(shù) function reducer(state, action) {     switch (action.type) {         case 'increment':           return {count: state.count + 1};         case 'decrement':            return {count: state.count - 1};         default:             throw new Error();     } }  function Counter() {     // 返回值:最新的state和dispatch函數(shù)     const [state, dispatch] = useReducer(reducer, initialState);     return (         <>             {/* // useReducer會根據(jù)dispatch的action,返回最終的state,并觸發(fā)rerender */}             Count: {state.count}             {/* // dispatch 用來接收一個 action參數(shù)「reducer中的action」,用來觸發(fā)reducer函數(shù),更新最新的狀態(tài) */}             <button onClick={() => dispatch({type: 'increment'})}>+</button>             <button onClick={() => dispatch({type: 'decrement'})}>-</button>         </>     ); } function render(){     ReactDOM.render(         <Counter />,         document.getElementById('root')     ); } render()

手寫useContext

使用

createContext 能夠創(chuàng)建一個 React 的  上下文(context),然后訂閱了這個上下文的組件中,可以拿到上下文中提供的數(shù)據(jù)或者其他信息。

基本的使用方法:

const MyContext = React.createContext()

如果要使用創(chuàng)建的上下文,需要通過 Context.Provider 最外層包裝組件,并且需要顯示的通過的方式傳入 value,指定 context 要對外暴露的信息。

子組件在匹配過程中只會匹配最新的  Provider,也就是說如果有下面三個組件:ContextA.Provider->A->ContexB.Provider->B->C

如果 ContextA 和 ContextB 提供了相同的方法,則 C 組件只會選擇 ContextB 提供的方法。

通過 React.createContext 創(chuàng)建出來的上下文,在子組件中可以通過 useContext 這個 Hook 獲取 Provider  提供的內(nèi)容

const {funcName} = useContext(MyContext);

從上面代碼可以發(fā)現(xiàn),useContext 需要將 MyContext 這個 Context 實(shí)例傳入,不是字符串,就是實(shí)例本身。

這種用法會存在一個比較尷尬的地方,父子組件不在一個目錄中,如何共享 MyContext 這個 Context 實(shí)例呢?

一般這種情況下,我會通過 Context Manager 統(tǒng)一管理上下文的實(shí)例,然后通過 export 將實(shí)例導(dǎo)出,在子組件中在將實(shí)例 import  進(jìn)來。

下面我們看看代碼,使用起來非常簡單

import React, { useState, useContext } from 'react'; import ReactDOM from 'react-dom'; let AppContext = React.createContext() function Counter() {     let { state, setState } = useContext(AppContext)     return (         <>             Count: {state.count}              <button onClick={() => setState({ number: state.number + 1 })}>+</button>         </>     ); } function App() {     let [state, setState] = useState({ number: 0 })     return (         <AppContext.Provider value={{ state, setState }}>             <div>                 <h2>{state.number}</h2>                 <Counter></Counter>             </div>         </AppContext.Provider>     ) } function render() {     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

要是用過vue的同學(xué),會發(fā)現(xiàn),這個機(jī)制有點(diǎn)類似vue 中提供的provide和inject

原理

原理非常簡單,由于createContext,Provider 不是ReactHook的內(nèi)容,  所以這里值需要實(shí)現(xiàn)useContext,如代碼所示,只需要一行代碼

import React, { useState } from 'react'; import ReactDOM from 'react-dom'; let AppContext = React.createContext() function useContext(context){     return context._currentValue } function Counter() {     let { state, setState } = useContext(AppContext)     return (         <>             <button onClick={() => setState({ number: state.number + 1 })}>+</button>         </>     ); } function App() {     let [state, setState] = useState({ number: 0 })     return (         <AppContext.Provider value={{ state, setState }}>             <div>                 <h2>{state.number}</h2>                 <Counter></Counter>             </div>         </AppContext.Provider>     ) } function render() {     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

手寫useEffect

使用

它跟class組件中的componentDidMount,componentDidUpdate,componentWillUnmount具有相同的用途,只不過被合成了一個api。

import React, { useState, useEffect} from 'react'; import ReactDOM from 'react-dom';  function App() {     let [number, setNumber] = useState(0)     useEffect(()=>{         console.log(number);     },[number])     return (          <div>             <h2>{number}</h2>             <button onClick={() => setNumber(number+1)}>+</button>         </div>     ) } function render() {     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

如代碼所示,支持兩個參數(shù),第二個參數(shù)也是用于監(jiān)聽的。當(dāng)監(jiān)聽數(shù)組中的元素有變化的時候再執(zhí)行作為第一個參數(shù)的執(zhí)行函數(shù)

原理

原理發(fā)現(xiàn)其實(shí)和useMemo,useCallback類似,只不過,前面前兩個有返回值,而useEffect沒有。(當(dāng)然也有返回值,就是那個執(zhí)行componentWillUnmount函功能的時候?qū)懙姆祷刂?,但是這里返回值跟前兩個作用不一樣,因?yàn)槟悴粫?/p>

let xxx = useEffect(()=>{         console.log(number);     },[number])

來接收返回值。

所以,忽略返回值,你可以直接看代碼,真的很類似,簡直可以用一模一樣來形容

import React, { useState} from 'react'; import ReactDOM from 'react-dom'; let lastEffectDependencies function useEffect(callback,dependencies){     if(lastEffectDependencies){         let changed = !dependencies.every((item,index)=>{             return item === lastEffectDependencies[index]         })         if(changed){             callback()             lastEffectDependencies = dependencies         }     }else{          callback()         lastEffectDependencies = dependencies     } } function App() {     let [number, setNumber] = useState(0)     useEffect(()=>{         console.log(number);     },[number])     return (          <div>             <h2>{number}</h2>             <button onClick={() => setNumber(number+1)}>+</button>         </div>     ) } function render() {     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

你以為這樣就結(jié)束了,其實(shí)還沒有,因?yàn)榈谝粋€參數(shù)的執(zhí)行時機(jī)錯了,實(shí)際上作為第一個參數(shù)的函數(shù)因?yàn)槭窃跒g覽器渲染結(jié)束后執(zhí)行的。而這里我們是同步執(zhí)行的。

所以需要改成異步執(zhí)行callback

import React, { useState} from 'react'; import ReactDOM from 'react-dom'; let lastEffectDependencies function useEffect(callback,dependencies){     if(lastEffectDependencies){         let changed = !dependencies.every((item,index)=>{             return item === lastEffectDependencies[index]         })         if(changed){             setTimeout(callback())             lastEffectDependencies = dependencies         }     }else{          setTimeout(callback())         lastEffectDependencies = dependencies     } } function App() {     let [number, setNumber] = useState(0)     useEffect(()=>{         console.log(number);     },[number])     return (          <div>             <h2>{number}</h2>             <button onClick={() => setNumber(number+1)}>+</button>         </div>     ) } function render() {     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

手寫useLayoutEffect

使用

官方解釋,這兩個hook基本相同,調(diào)用時機(jī)不同,請全部使用useEffect,除非遇到bug或者不可解決的問題,再考慮使用useLayoutEffect。

原理

原理跟useEffect一樣,只是調(diào)用時機(jī)不同

上面說到useEffect的調(diào)用時機(jī)是瀏覽器渲染結(jié)束后執(zhí)行的,而useLayoutEffect是在DOM構(gòu)建完成,瀏覽器渲染前執(zhí)行的。

所以這里需要把宏任務(wù)setTimeout改成微任務(wù)

import React, { useState} from 'react'; import ReactDOM from 'react-dom'; let lastEffectDependencies function useLayouyEffect(callback,dependencies){     if(lastEffectDependencies){         let changed = !dependencies.every((item,index)=>{             return item === lastEffectDependencies[index]         })         if(changed){             Promise.resolve().then(callback())             lastEffectDependencies = dependencies         }     }else{          Promise.resolve().then(callback())         lastEffectDependencies = dependencies     } } function App() {     let [number, setNumber] = useState(0)     useLayouyEffect(()=>{         console.log(number);     },[number])     return (          <div>             <h2>{number}</h2>             <button onClick={() => setNumber(number+1)}>+</button>         </div>     ) } function render() {     ReactDOM.render(         <App />,         document.getElementById('root')     ); } render()

到此,相信大家對“ReactHook核心原理是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

分享標(biāo)題:ReactHook核心原理是什么
瀏覽路徑:http://aaarwkj.com/article46/iijdhg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、搜索引擎優(yōu)化、網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作、網(wǎng)站導(dǎo)航、外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)
麻豆国产传媒片在线观看| 色综合久久综合香梨网| 日韩亚洲毛片全在线播放| 日韩少妇一级淫片免费| 日韩在线一区二区视频| 东京热男人的av天堂| 激情自拍偷拍合集一部| 精品亚洲在线一区二区| 亚洲福利一区二区在线| 久久综合伊人欧美精品| 日本一区二区三区视频| 色综合久久国产原创野外| 国产白丝免费在线观看| 风流少妇奶真白摸的好爽| 国产传媒免费在线播放| av电影网站中文字幕| 国产午夜三级视频在线观看| 亚洲视频精品一区二区三区| 欧美一区二区三区十区| 伊人狼人综合视频在线播放| 日本一区二区三区高清在线| 国产精品一区二区激情视频| 欧美另类不卡在线观看| 国产一区二区三区婷婷| 日韩中文不卡人成在线视频| 国产传媒在线播放一区| av资源在线观看少妇丰满| 情侣自拍偷拍亚洲天堂区| 久久精品国产亚洲av久| 久久亚洲精品中文字幕一| 欧美乱与老熟妇视频观看| 欧美一级免费黄片在线播放| 亚洲成人午夜免费在线观看| 国产av爆操黑丝美女| 国产精品久久亚洲一区二区| 可以看黄片的在线观看| 欧美一区二区三区蜜桃| 国产男生午夜福利网站| 日本韩国三级理伦久久久| 色自拍偷拍另类欧洲美女| 黄色大全欧美在线观看|