React(coderwhy)- 08(Hooks)

news2024/12/23 19:42:39

认识和体验Hooks

为什么需要Hook?

Hook 是 React 16.8 的新增特性,它可以让我们在 不编写class的情况下 使用 state以及其他的React特性 (比如生命周期)。
我们先来思考一下class组件相对于函数式组件有什么优势?比较常见的是下面的优势:
class组件可以 定义自己的state ,用来 保存组件自己内部的状态
         函数式组件不可以,因为函数每次调用都会产生新的临时变量;
class组件有 自己的生命周期 ,我们可以在 对应的生命周期中完成自己的逻辑
         比如在componentDidMount中发送网络请求,并且该生命周期函数只会执行一次;
         函数式组件在学习hooks之前,如果在函数中发送网络请求,意味着每次重新渲染都会重新发送一次网络请求;
class组件可以 在状态改变时只会重新执行render函数 以及 我们希望重新调用的生命周期函数componentDidUpdate 等;
         函数式组件在重新渲染时,整个函数都会被执行,似乎没有什么地方可以只让它们调用一次;
所以,在Hook出现之前,对于上面这些情况我们通常都会编写class组件。

Class组件存在的问题

复杂组件变得难以理解:
         我们在最初编写一个class组件时,往往逻辑比较简单,并不会非常复杂。但是 随着业务的增多 ,我们的 class组件会变得越来越复杂
         比如componentDidMount中,可能就会包含大量的逻辑代码:包括 网络请求、一些事件的监听 (还需要在
componentWillUnmount中移除);
         而对于这样的class实际上非常难以拆分:因为 它们的逻辑往往混在一起 强行拆分反而会造成过度设计 增加代码的复杂度
难以理解的class:
         很多人 发现学习ES6的class是学习React的一个障碍
         比如在class中,我们 必须搞清楚this的指向到底是谁 ,所以需要花很多的精力去学习this;
         虽然我认为前端开发人员必须掌握this,但是依然处理起来非常麻烦;
组件复用状态很难
         在前面为了一些状态的复用我们需要 通过高阶组件
         像我们之前学习的 redux中connect或者react-router中的withRouter ,这些高阶组件设计的目的就是 为了状态的复用
         或者 类似于Provider、Consumer来共享一些状态 ,但是 多次使用Consumer时,我们的代码就会存在很多嵌套
         这些代码让我们 不管是编写和设计上来说,都变得非常困难

Hook的出现

Hook的出现,可以解决上面提到的这些问题;
简单总结一下hooks:
         它可以让我们在不编写class的情况下使用state以及其他的React特性
         但是我们 可以由此延伸出非常多的用法 来让我们前面所提到的问题得到解决
Hook的使用场景:
         Hook的出现 基本可以代替我们之前所有使用class组件的地方
         但是如果是一个旧的项目,你 并不需要直接将所有的代码重构为Hooks ,因为 它完全向下兼容,你可以渐进式的来使用它
         Hook 只能在函数组件中使用,不能在类组件 或者函数组件之外的地方使用
在我们继续之前,请记住 Hook 是:
         完全可选的 你无需重写任何已有代码就可以在一些组件中尝试 Hook。但是如果你不想,你不必现在就去学习或使用 Hook。
         100% 向后兼容的 Hook 不包含任何破坏性改动。
         现在可用 Hook 已发布于 v16.8.0。

import React, { PureComponent } from 'react'

class HelloWord extends PureComponent {
  constructor(props) {
    super(props)

    this.state = {
      message: "Hello World"
    }
  }

  changeText() {
    this.setState({ message: "你好啊, 李银河!" })
  }

  render() {
    const { message } = this.state

    return (
      <div>
        <h2>内容: {message}</h2>
        <button onClick={e => this.changeText()}>修改文本</button>
      </div>
    )
  }
}

function HelloWorld2(props) {
  let message = "Hello World"

  // 函数式组件存在的最大的缺陷:
  // 1.组件不会被重新渲染: 修改message之后, 组件知道自己要重新进行渲染吗? 
  // 2.如果页面重新渲染: 函数会被重新执行, 第二次重新执行时, 会重新给message赋值为hello world
  // 3.类似于生命周期的回调函数: 也是没有的

  return (
    <div>
      <h2>内容2: {message}</h2>
      <button onClick={e => message = "你好啊, 李银河!"}>修改文本</button>
    </div>
  )
}

export class App extends PureComponent {
  render() {
    return (
      <div>
        <HelloWord/>
        <hr />
        <HelloWorld2/>
      </div>
    )
  }
}

export default App

计数器案例对比 

State/Effect

useState解析


认识useState 


认识Effect Hook 

需要清除Effect

 

import React, { memo, useEffect } from 'react'
import { useState } from 'react'

const App = memo(() => {
  const [count, setCount] = useState(0)

  // 负责告知react, 在执行完当前组件渲染之后要执行的副作用代码
  useEffect(() => {
    // 1.监听事件
    // const unubscribe = store.subscribe(() => {
    // })
    // function foo() {
    // }
    // eventBus.on("why", foo)
    console.log("监听redux中数据变化, 监听eventBus中的why事件")

    // 返回值: 回调函数 => 组件被重新渲染或者组件卸载的时候执行
    return () => {
      console.log("取消监听redux中数据变化, 取消监听eventBus中的why事件")
    }
  })

  return (
    <div>
      <button onClick={e => setCount(count+1)}>+1({count})</button>
    </div>
  )
})

export default App

使用多个Effect

使用Hook的其中一个目的就是解决class中生命周期经常将很多的逻辑放在一起的问题:
         比如网络请求、事件监听、手动修改DOM,这些往往都会放在componentDidMount中;
使用Effect Hook,我们可以将它们分离到不同的useEffect中:
         代码不再给出
Hook 允许我们按照代码的用途分离它们, 而不是像生命周期函数那样:
         React 将按照 effect 声明的顺序依次调用组件中的 每一个 effect;

 Effect性能优化

 

import React, { memo, useEffect } from 'react'
import { useState } from 'react'

const App = memo(() => {
  const [count, setCount] = useState(0)

  // 负责告知react, 在执行完当前组件渲染之后要执行的副作用代码
  useEffect(() => {
    // 1.修改document的title(1行)
    console.log("修改title")
  })

  // 一个函数式组件中, 可以存在多个useEffect
  useEffect(() => {
    // 2.对redux中数据变化监听(10行)
    console.log("监听redux中的数据")
    return () => {
      // 取消redux中数据的监听
    }
  })

  useEffect(() => {
    // 3.监听eventBus中的why事件(15行)
    console.log("监听eventBus的why事件")
    return () => {
      // 取消eventBus中的why事件监听
    }
  })

  return (
    <div>
      <button onClick={e => setCount(count+1)}>+1({count})</button>
    </div>
  )
})

export default App

执行时机 - 控制回调执行:

import React, { memo, useEffect } from 'react'
import { useState } from 'react'

const App = memo(() => {
  const [count, setCount] = useState(0)
  const [message, setMessage] = useState("Hello World")

  useEffect(() => {
    console.log("修改title:", count)
  }, [count])

  useEffect(() => {
    console.log("监听redux中的数据")
    return () => {}
  }, [])

  useEffect(() => {
    console.log("监听eventBus的why事件")
    return () => {}
  }, [])

  useEffect(() => {
    console.log("发送网络请求, 从服务器获取数据")

    return () => {
      console.log("会在组件被卸载时, 才会执行一次")
    }
  }, [])

  return (
    <div>
      <button onClick={e => setCount(count+1)}>+1({count})</button>
      <button onClick={e => setMessage("你好啊")}>修改message({message})</button>
    </div>
  )
})

export default App

Context/Reducer

useContext的使用

import { createContext } from "react";

const UserContext = createContext()
const ThemeContext = createContext()


export {
  UserContext,
  ThemeContext
}
在组件中使用:
import React, { memo, useContext } from 'react'
import { UserContext, ThemeContext } from "./context"

const App = memo(() => {
  // 使用Context
  const user = useContext(UserContext)
  const theme = useContext(ThemeContext)

  return (
    <div>
      <h2>User: {user.name}-{user.level}</h2>
      <h2 style={{color: theme.color, fontSize: theme.size}}>Theme</h2>
    </div>
  )
})

export default App
 

useReducer 

useState的替代方案

 

import React, { memo, useReducer } from 'react'
// import { useState } from 'react'

function reducer(state, action) {
  switch(action.type) {
    case "increment":
      return { ...state, counter: state.counter + 1 }
    case "decrement":
      return { ...state, counter: state.counter - 1 }
    case "add_number":
      return { ...state, counter: state.counter + action.num }
    case "sub_number":
      return { ...state, counter: state.counter - action.num }
    default:
      return state
  }
}

// useReducer+Context => redux

const App = memo(() => {
  // const [count, setCount] = useState(0)
  const [state, dispatch] = useReducer(reducer, { counter: 0, friends: [], user: {} })

  // const [counter, setCounter] = useState()
  // const [friends, setFriends] = useState()
  // const [user, setUser] = useState()

  return (
    <div>
      {/* <h2>当前计数: {count}</h2>
      <button onClick={e => setCount(count+1)}>+1</button>
      <button onClick={e => setCount(count-1)}>-1</button>
      <button onClick={e => setCount(count+5)}>+5</button>
      <button onClick={e => setCount(count-5)}>-5</button>
      <button onClick={e => setCount(count+100)}>+100</button> */}

      <h2>当前计数: {state.counter}</h2>
      <button onClick={e => dispatch({type: "increment"})}>+1</button>
      <button onClick={e => dispatch({type: "decrement"})}>-1</button>
      <button onClick={e => dispatch({type: "add_number", num: 5})}>+5</button>
      <button onClick={e => dispatch({type: "sub_number", num: 5})}>-5</button>
      <button onClick={e => dispatch({type: "add_number", num: 100})}>+100</button>
    </div>
  )
})

export default App

Callback/Memo

useCallback

import React, { memo, useState, useCallback, useRef } from 'react'

// useCallback性能优化的点:
// 1.当需要将一个函数传递给子组件时, 最好使用useCallback进行优化, 将优化之后的函数, 传递给子组件

// props中的属性发生改变时, 组件本身就会被重新渲染
const HYHome = memo(function(props) {
  const { increment } = props
  console.log("HYHome被渲染")
  return (
    <div>
      <button onClick={increment}>increment+1</button>

      {/* 100个子组件 */}
    </div>
  )
})

const App = memo(function() {
  const [count, setCount] = useState(0)
  const [message, setMessage] = useState("hello")

  // 闭包陷阱: useCallback
  // const increment = useCallback(function foo() {
  //   console.log("increment")
  //   setCount(count+1)
  // }, [count])

  // 进一步的优化: 当count发生改变时, 也使用同一个函数(了解)
  // 做法一: 将count依赖移除掉, 缺点: 闭包陷阱
  // 做法二: useRef, 在组件多次渲染时, 返回的是同一个值
  const countRef = useRef()
  countRef.current = count
  const increment = useCallback(function foo() {
    console.log("increment")
    setCount(countRef.current + 1)
  }, [])

  // 普通的函数
  // const increment = () => {
  //   setCount(count+1)
  // }

  return (
    <div>
      <h2>计数: {count}</h2>
      <button onClick={increment}>+1</button>

      <HYHome increment={increment}/>

      <h2>message:{message}</h2>
      <button onClick={e => setMessage(Math.random())}>修改message</button>
    </div>
  )
})


// function foo(name) {
//   function bar() {
//     console.log(name)
//   }
//   return bar
// }

// const bar1 = foo("why")
// bar1() // why
// bar1() // why

// const bar2 = foo("kobe")
// bar2() // kobe

// bar1() // why

export default App

useMemo 

 

import React, { memo, useCallback } from 'react'
import { useMemo, useState } from 'react'


const HelloWorld = memo(function(props) {
  console.log("HelloWorld被渲染~")
  return <h2>Hello World</h2>
})


function calcNumTotal(num) {
  // console.log("calcNumTotal的计算过程被调用~")
  let total = 0
  for (let i = 1; i <= num; i++) {
    total += i
  }
  return total
}

const App = memo(() => {
  const [count, setCount] = useState(0)

  // const result = calcNumTotal(50)

  // 1.不依赖任何的值, 进行计算
  const result = useMemo(() => {
    return calcNumTotal(50)
  }, [])

  // 2.依赖count
  // const result = useMemo(() => {
  //   return calcNumTotal(count*2)
  // }, [count])

  // 3.useMemo和useCallback的对比
  function fn() {}
  // const increment = useCallback(fn, [])
  // const increment2 = useMemo(() => fn, [])


  // 4.使用useMemo对子组件渲染进行优化
  // const info = { name: "why", age: 18 }
  const info = useMemo(() => ({name: "why", age: 18}), [])

  return (
    <div>
      <h2>计算结果: {result}</h2>
      <h2>计数器: {count}</h2>
      <button onClick={e => setCount(count+1)}>+1</button>

      <HelloWorld result={result} info={info} />
    </div>
  )
})

export default App

Ref / LayoutEffect

useRef

绑定DOM:

import React, { memo, useRef } from 'react'

const App = memo(() => {
  const titleRef = useRef()
  const inputRef = useRef()
  
  function showTitleDom() {
    console.log(titleRef.current)
    inputRef.current.focus()
  }

  return (
    <div>
      <h2 ref={titleRef}>Hello World</h2>
      <input type="text" ref={inputRef} />
      <button onClick={showTitleDom}>查看title的dom</button>
    </div>
  )
})

export default App

useRef绑定值-解决闭包陷阱:

import React, { memo, useRef } from 'react'
import { useCallback } from 'react'
import { useState } from 'react'

let obj = null

const App = memo(() => {
  const [count, setCount] = useState(0)
  const nameRef = useRef()
  console.log(obj === nameRef)
  obj = nameRef

  // 通过useRef解决闭包陷阱
  const countRef = useRef()
  countRef.current = count

  const increment = useCallback(() => {
    setCount(countRef.current + 1)
  }, [])

  return (
    <div>
      <h2>Hello World: {count}</h2>
      <button onClick={e => setCount(count+1)}>+1</button>
      <button onClick={increment}>+1</button>
    </div>
  )
})

export default App
useImperativeHandle  

import React, { memo, useRef, forwardRef, useImperativeHandle } from 'react'

const HelloWorld = memo(forwardRef((props, ref) => {

  const inputRef = useRef()

  // 子组件对父组件传入的ref进行处理
  useImperativeHandle(ref, () => {
    return {
      focus() {
        console.log("focus")
        inputRef.current.focus()
      },
      setValue(value) {
        inputRef.current.value = value
      }
    }
  })

  return <input type="text" ref={inputRef}/>
}))


const App = memo(() => {
  const titleRef = useRef()
  const inputRef = useRef()

  function handleDOM() {
    // console.log(inputRef.current)
    inputRef.current.focus()
    // inputRef.current.value = ""
    inputRef.current.setValue("哈哈哈")
  }

  return (
    <div>
      <h2 ref={titleRef}>哈哈哈</h2>
      <HelloWorld ref={inputRef}/>
      <button onClick={handleDOM}>DOM操作</button>
    </div>
  )
})

export default App

useLayoutEffect 

 

自定义Hooks使用

自定义Hook

打印生命周期:

import React, { memo, useEffect, useState } from 'react'

function useLogLife(cName) {
  useEffect(() => {
    console.log(cName + "组件被创建")
    return () => {
      console.log(cName + "组件被销毁")
    }
  }, [cName])
}

const Home = memo(() => {
  useLogLife("home")

  return <h1>Home Page</h1>
})

const About = memo(() => {
  useLogLife("about")

  return <h1>About Page</h1>
})

const App = memo(() => {
  const [isShow, setIsShow] = useState(true)

  useLogLife("app")

  return (
    <div>
      <h1>App Root Component</h1>
      <button onClick={e => setIsShow(!isShow)}>切换</button>
      { isShow && <Home/> }
      { isShow && <About/> }
    </div>
  )
})

export default App

自定义Hook练习 

 创建Context:

import { createContext } from "react";

const UserContext = createContext()
const TokenContext = createContext()

export {
  UserContext,
  TokenContext
}

在入口文件中设置:

import { UserContext, TokenContext } from "./12_自定义Hooks/context"

import App from "./12_自定义Hooks/02_Context获取数据"

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <UserContext.Provider value={{name: "why", level: 99}}>
    <TokenContext.Provider value={'coderwhy'}>
      <App />
    </TokenContext.Provider>
  </UserContext.Provider>
);

Context抽离:

import { useContext } from "react"
import { UserContext, TokenContext } from "../context"

function useUserToken() {
  const user = useContext(UserContext)
  const token = useContext(TokenContext)

  return [user, token]
}

export default useUserToken

在组件中使用:

import React, { memo } from 'react'
import { useUserToken } from "./hooks"

// User/Token

const Home = memo(() => {
  const [user, token] = useUserToken()

  return <h1>Home Page: {user.name}-{token}</h1>
})

const About = memo(() => {
  const [user, token] = useUserToken()

  return <h1>About Page: {user.name}-{token}</h1>
})

const App = memo(() => {
  return (
    <div>
      <h1>App Root Component</h1>
      <Home/>
      <About/>
    </div>
  )
})

export default App

 抽离:

import { useState, useEffect } from "react"

function useScrollPosition() {
  const [ scrollX, setScrollX ] = useState(0)
  const [ scrollY, setScrollY ] = useState(0)

  useEffect(() => {
    function handleScroll() {
      // console.log(window.scrollX, window.scrollY)
      setScrollX(window.scrollX)
      setScrollY(window.scrollY)
    }

    window.addEventListener("scroll", handleScroll)
    return () => {
      window.removeEventListener("scroll", handleScroll)
    }
  }, [])

  return [scrollX, scrollY]
}

export default useScrollPosition

在组件中使用:

import React, { memo } from 'react'
import useScrollPosition from './hooks/useScrollPosition'
import "./style.css"

const Home = memo(() => {
  const [scrollX, scrollY] = useScrollPosition()

  return <h1>Home Page: {scrollX}-{scrollY}</h1>
})

const About = memo(() => {
  const [scrollX, scrollY] = useScrollPosition()

  return <h1>About Page: {scrollX}-{scrollY}</h1>
})

const App = memo(() => {
  return (
    <div className='app'>
      <h1>App Root Component</h1>
      <Home/>
      <About/>
    </div>
  )
})

export default App

 抽离:

import { useEffect } from "react"
import { useState } from "react"

function useLocalStorage(key) {
  // 1.从localStorage中获取数据, 并且数据数据创建组件的state
  const [data, setData] = useState(() => {
    const item = localStorage.getItem(key)
    if (!item) return ""
    return JSON.parse(item)
  })

  // 2.监听data改变, 一旦发生改变就存储data最新值
  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(data))
  }, [data])

  // 3.将data/setData的操作返回给组件, 让组件可以使用和修改值
  return [data, setData]
}


export default useLocalStorage
在组件中使用:
import React, { memo } from 'react'
import { useEffect } from 'react'
import { useState } from 'react'
import useLocalStorage from './hooks/useLocalStorage'

const App = memo(() => {
  // 通过key, 直接从localStorage中获取一个数据
  // const [token, setToken] = useState(localStorage.getItem("token"))
  // useEffect(() => {
  //   localStorage.setItem("token", token)
  // }, [token])
  const [token, setToken] = useLocalStorage("token")
  function setTokenHandle() {
    setToken("james")
  }

  // const [avatarUrl, setAvatarUrl] = useState(localStorage.getItem("avatarUrl"))
  // useEffect(() => {
  //   localStorage.setItem("avatarUrl", avatarUrl)
  // }, [avatarUrl])
  const [avatarUrl, setAvatarUrl] = useLocalStorage("avatarUrl")
  function setAvatarUrlHandle() {
    setAvatarUrl("http://www.james.com/cba.png")
  }

  return (
    <div className='app'>
      <h1>App Root Component: {token}</h1>
      <button onClick={setTokenHandle}>设置token</button>
      <h1>avatarURL: {avatarUrl}</h1>
      <button onClick={setAvatarUrlHandle}>设置新头像地址</button>
    </div>
  )
})

export default App


redux hooks 


useId 


SSR同构应用 


Hydration 


useId的作用 

import React, { memo, useId, useState } from 'react'

const App = memo(() => {
  const [count, setCount] = useState(0)

  const id = useId()
  console.log(id)

  return (
    <div>
      <button onClick={e => setCount(count+1)}>count+1:{count}</button>

      <label htmlFor={id}>
        用户名:<input id={id} type="text" />
      </label>
    </div>
  )
})

export default App

useTransition 

js:

import { faker } from '@faker-js/faker';

const namesArray = []

for (let i = 0; i < 10000; i++) {
  namesArray.push(faker.name.fullName())
}

export default namesArray
组件:
import React, { memo, useState, useTransition } from 'react'
import namesArray from './namesArray'

const App = memo(() => {
  const [showNames, setShowNames] = useState(namesArray)
  const [ pending, startTransition ] = useTransition()

  function valueChangeHandle(event) {
    startTransition(() => {
      const keyword = event.target.value
      const filterShowNames = namesArray.filter(item => item.includes(keyword))
      setShowNames(filterShowNames)
    })
  }

  return (
    <div>
      <input type="text" onInput={valueChangeHandle}/>
      <h2>用户名列表: {pending && <span>data loading</span>} </h2>
      <ul>
        {
          showNames.map((item, index) => {
            return <li key={index}>{item}</li>
          })
        }
      </ul>
    </div>
  )
})

export default App

useDeferredValue 

 

import React, { memo, useState, useDeferredValue } from 'react'
import namesArray from './namesArray'

const App = memo(() => {
  const [showNames, setShowNames] = useState(namesArray)
  const deferedShowNames = useDeferredValue(showNames)

  function valueChangeHandle(event) {
    const keyword = event.target.value
    const filterShowNames = namesArray.filter(item => item.includes(keyword))
    setShowNames(filterShowNames)
  }

  return (
    <div>
      <input type="text" onInput={valueChangeHandle}/>
      <h2>用户名列表: </h2>
      <ul>
        {
          deferedShowNames.map((item, index) => {
            return <li key={index}>{item}</li>
          })
        }
      </ul>
    </div>
  )
})

export default App

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/144597.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Exynos_4412——IIC总线概述

目录 一、IIC总线概述 1.1IIC总线简介 1.2IIC总线通信过程 1.3IIC总线寻址方式 二、IIC总线信号实现 2.1起始信号与停止信号 2.2字节传送与应答 2.3同步信号 三、典型IIC时序 四、小作业 一、IIC总线概述 1.1IIC总线简介 IIC总线IIC总线是Philips公司在八十年代初推…

[VP]河南第十三届ICPC大学生程序竞赛 L.手动计算

前言 传送门 : 题意 : 给定两个椭圆 的方程 , 要求 求出椭圆并集的面积之和 思路 : 本题很显然是积分 或者 计算几何的问题 对于积分的做法, 无非就是根据积分公式求出第一象限的面积 之后拓展到后面四个象限。(奈何我懒, 连两个椭圆的焦点都不想求更别提后面的积分公式了)…

Git遇到冲突?解决也太简单了

程序员宝藏库&#xff1a;https://gitee.com/sharetech_lee/CS-Books-Store git冲突是开发过程中很难避免的&#xff0c;对很多git初学者来说也是比较有障碍和门槛的一部分知识。 我认为要想彻底理解一个问题&#xff0c;首先要清楚这个问题是怎么产生的&#xff0c;然后才可以…

大数据NiFi(八):NiFi集群页面的组件工具栏介绍

NiFi集群页面的组件工具栏介绍 一、处理器(Processor)

WebLogic-执行队列

一&#xff0c;Tuning the Application Server 二&#xff0c;执行队列 Using Work Managers to Optimize Scheduled WorkThis chapter describes how WebLogic Server 12.1.3 lets you configure how your application prioritizes the execution of its work using a Work Ma…

java实现pdf转word,解决个别排版错乱问题

项目中要实现客户上传完pdf&#xff0c;上传成功后直接就转成word格式的&#xff0c;之前网上一些免费的转出来的word大致还行&#xff0c;但是有些排版就错乱了&#xff0c;如下图:下面这个是用java改造后的&#xff0c;效果如下&#xff0c;排版整齐&#xff0c;和pdf中的格式…

[总结] DDPM Diffusion模型各阶段训练和采样过程方案细节和代码逻辑汇总

DDPM Diffusion模型训练和采样过程细节汇总算法回顾框架理解DDPM训练过程采样过程Text-guiled DDPM训练过程采样过程Null-text guiled DDPM训练过程采样过程项目代码训练过程![在这里插入图片描述](https://img-blog.csdnimg.cn/f6213f8e584b4142b0c5a016cd23b63a.png)采样过程…

c++ std::funciona代替函数指针——结合std::bind

一、介绍std::function std::function是函数模板类&#xff08;是一个类&#xff09;。包含在#include <functional> 中。以前没有这个类的时候&#xff0c;我们在想定义一个回调函数指针&#xff0c;非常的麻烦。我们通常这样的定义&#xff1a; typedef void&#x…

智能小便冲洗器行业市场运行态势及未来发展潜力分析

2023-2029年中国智能小便冲洗器行业市场运行态势及未来发展潜力报告报告编号&#xff1a;1690632免费目录下载&#xff1a;http://www.cninfo360.com/yjbg/jdhy/cwjd/20230105/1690632.html本报告著作权归博研咨询所有&#xff0c;未经书面许可&#xff0c;任何组织和个人不得以…

Python人工智能之人脸识别face_recognition安装

face_recognition 模块使用系统环境搭建 系统环境 Ubuntu / deepin操作系统Python 3.6pycharm 开发工具 开发环境配置&#xff0c;安装各种系统包 人脸检测基于dlib&#xff0c;dlib依赖Boost和cmake 在windows中如果要使用dlib还是比较麻烦的&#xff0c;如果想省时间可以在…

【关于Linux中----文件系统、inode、软硬链接和动静态库】

文章目录一、理解文件系统和inode二、硬链接与软链接三、动静态库3.1、静态库与动态库3.2、生成静态库3.3、生成动态库一、理解文件系统和inode 在我前几篇博客中谈到的有关文件的话题&#xff0c;它们统一指的都是打开的文件&#xff0c;那么在这里&#xff0c;我要谈一下没有…

Java基础之《netty(22)—netty编码解码机制》

一、编码和解码的基本介绍 1、编写网络应用程序时&#xff0c;因为数据在网络中传输的都是二进制字节码数据&#xff0c;在发数据时就需要编码&#xff0c;接收数据时就需要解码 2、codec&#xff08;编解码器&#xff09;的组成部分有两个&#xff1a;decoder&#xff08;解…

看小红书排行榜,解构热点背后的出圈密码

导语&#xff1a; 随着消费升级&#xff0c;新中式茶饮也悄然“起风了”&#xff0c;传统茶从老一辈人的茶杯里&#xff0c;通过创新再造&#xff0c;成为年轻人的社交“新”头好&#xff0c;其衍生的“围炉煮茶”更成为小红书平台的热门话题。高流量曝光之路背后&#xff0c;…

一个精美的登录界面原来是这样做的

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏 玩归玩闹归闹&#xff0c;别拿java开玩笑 —————————————————— ⭐相关文章⭐ -通过窗口看…

隐形纱窗行业市场经营管理及发展趋势研究分析

2023-2029年中国隐形纱窗行业市场经营管理及发展趋势研究报告报告编号&#xff1a;1690619本报告著作权归博研咨询所有&#xff0c;未经书面许可&#xff0c;任何组织和个人不得以任何形式复制、传播或输出中华人民共和国境外。任何未经授权使用本报告的相关商业行为都将违反《…

【操作系统】计算机内存管理

1.内存管理目标rom-ram &#xff08;1&#xff09;为啥要做内存管理 计算机不可能所以用户进程和系统所需要的全部程序和数据放入主存&#xff0c;所以操作系统必须对内存空间进行合理有效的分配内存管理功能 内存分配回收&#xff1a;主存储器&#xff08;物理内存&#xff…

UOS系统启动盘制作

UOS系统启动盘制作一、统信启动盘制作工具1、UOS系统1&#xff09;在启动器打开启动盘制作工具![在这里插入图片描述](https://img-blog.csdnimg.cn/d51bf22e25a846cdb99f7f6317e9447f.png)2&#xff09;选择镜像3&#xff09;选择优盘并格式化4&#xff09;开始制作5&#xff…

第06章 面向对象编程(基础部分oop)

1、单独用变量来解决&#xff1a;不利于数据的管理, 把猫的三个属性拆开了。 2、使用数组的方式解决&#xff1a; 数据类型体现不出来&#xff0c;由于数组中的类型是一致的&#xff0c;所有不能体现出不同的数据类型。 只能通过下标的方式获取信息&#xff0c;这样会造成变量…

sql练习题3

学生表练习 1、查询所有的课程的名称以及对应的任课老师姓名 select course.cname,teacher.tname from course inner join teacher on course.teacher_id teacher.tid;2、查询学生表中男女生各有多少人 select gender as 性别,count(gender) as 个数 from student group b…

Java面向对象:封装、JavaBean和综合案例

目录封装基本概念总结如何更好的封装总结JavaBean补充知识&#xff1a;成员变量&#xff0c;局部变量区别综合案例封装 面向对象的三大特征:封装&#xff0c;继承&#xff0c;多态。 封装:告诉我们&#xff0c;如何正确设计对象的属性和方法。 封装的原则:对象代表什么&#x…