首页 > 其他分享 >react hook应用详解+diff 理解 + 父子组件渲染

react hook应用详解+diff 理解 + 父子组件渲染

时间:2024-10-28 20:44:54浏览次数:6  
标签:count React return DOM react hook props 组件 diff

文章目录

React Hook函数全解

1. useState

  • 参数
    • 初始值:可以是任意类型(数字、字符串、对象、数组等),用于设定状态的初始状态。例如const [count, setCount] = useState(0),这里0就是count状态的初始值。
  • 应用实例
import React, { useState } from 'react';
function Counter() {
    const [count, setCount] = useState(0);
    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={() => setCount(count + 1)}>
                Click me
            </button>
        </div>
    );
}
  • 应用场景
    • 用于在函数组件中管理简单的状态,如表单输入值、开关状态、计数器等。

2. useEffect

  • 参数
    • 第一个参数:一个函数,在组件挂载后、更新后(如果依赖项改变)和卸载前执行。这个函数用于执行副作用操作,如数据获取、订阅事件、手动修改DOM等。
    • 第二个参数:依赖项数组,用于指定副作用函数在哪些状态或属性变化时重新执行。空数组表示只在组件挂载和卸载时执行一次;如果省略,副作用函数会在每次组件渲染后都执行。
  • 应用实例
import React, { useState, useEffect } from 'react';
function Example() {
    const [count, setCount] = useState(0);
    useEffect(() => {
        document.title = `You clicked ${count} times`;
    }, [count]);
    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={() => setCount(count + 1)}>
                Click me
            </button>
        </div>
    );
}
  • 应用场景
    • 数据获取:在组件挂载时从API获取数据并更新状态,如获取用户列表展示在页面上。
    • 事件监听:添加和清除事件监听器,比如在组件挂载时添加window.scroll事件监听器,在组件卸载时清除它,防止内存泄漏。

3. useContext

  • 参数
    • 接收一个Context对象,这个对象是通过React.createContext创建的。例如const value = useContext(MyContext),其中MyContext是已创建的上下文对象。
  • 应用实例
import React, { createContext, useContext, useState } from 'react';
const ThemeContext = createContext();
function App() {
    const [theme, setTheme] = useState('light');
    return (
        <ThemeContext.Provider value={theme}>
            <Toolbar />
        </ThemeContext.Provider>
    );
}
function Toolbar() {
    const theme = useContext(ThemeContext);
    return <button onClick={() => setTheme(theme === 'light'? 'dark' : 'light')}>Toggle Theme</button>;
}
  • 应用场景
    • 跨组件共享数据,避免多层级组件通过props层层传递数据,如主题、用户认证信息等。

4. useReducer

  • 参数
    • 第一个参数:一个reducer函数,它接收当前状态和一个action作为参数,并返回新的状态。例如(state, action) => { switch (action.type) {... } return newState; }
    • 第二个参数:初始状态,和useState的初始值类似。
    • 第三个参数(可选):一个初始化函数,用于惰性初始化状态。
  • 应用实例
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
    switch (action.type) {
        case 'increment':
            return { count: state.count + 1 };
        case 'decrement':
            return { count: state.count - 1 };
        default:
            return state;
    }
}
function Counter() {
    const [state, dispatch] = useReducer(reducer, initialState);
    return (
        <div>
            <p>Count: {state.count}</p>
            <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
            <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
        </div>
    );
}
  • 应用场景
    • 当状态逻辑比较复杂,如状态更新依赖于前一个状态,或者有多个子状态需要一起更新时,使用useReducer可以使状态管理更清晰。

5. useCallback

  • 参数
    • 第一个参数:一个内联函数,这个函数会被缓存。
    • 第二个参数:依赖项数组,用于指定什么时候重新创建这个缓存的函数。
  • 应用实例
import React, { useState, useCallback } from 'react';
function Parent() {
    const [count, setCount] = useState(0);
    const memoizedCallback = useCallback(() => {
        // 一些复杂的计算或操作
        console.log(count);
    }, [count]);
    return (
        <div>
            <Child callback={memoizedCallback} />
            <button onClick={() => setCount(count + 1)}>Update Count</button>
        </div>
    );
}
function Child({ callback }) {
    // 使用传入的回调函数
    return <button onClick={callback}>Execute Callback</button>;
}
  • 应用场景
    • 优化子组件的重新渲染,当传递给子组件的回调函数依赖的状态没有改变时,避免子组件因为函数引用变化而重新渲染。

6. useMemo

  • 参数
    • 第一个参数:一个函数,用于计算一个值。
    • 第二个参数:依赖项数组,用于指定什么时候重新计算这个值。
  • 应用实例
import React, { useState, useMemo } from 'react';
function ExpensiveComponent({ a, b }) {
    const result = useMemo(() => {
        // 复杂的计算
        console.log('Calculating...');
        return a * b;
    }, [a, b]);
    return <div>Result: {result}</div>;
}
function App() {
    const [a, setA] = useState(2);
    const [b, setB] = useState(3);
    return (
        <div>
            <ExpensiveComponent a={a} b={b} />
            <button onClick={() => setA(a + 1)}>Update A</button>
            <button onClick={() => setB(b + 1)}>Update B</button>
        </div>
    );
}
  • 应用场景
    • 用于缓存计算结果,避免在每次组件渲染时都进行昂贵的计算,只有当依赖项改变时才重新计算。

7. useRef

  • 参数
    • 初始值:可以是任何类型的值,用于初始化ref对象的current属性。
  • 应用实例
import React, { useRef, useEffect } from 'react';
function TextInputWithFocusButton() {
    const inputEl = useRef(null);
    const onButtonClick = () => {
        inputEl.current.focus();
    };
    return (
        <>
            <input ref={inputEl} type="text" />
            <button onClick={onButtonClick}>Focus the input</button>
        </>
    );
}
  • 应用场景
    • 访问DOM元素或保存一个可变的值,在组件的整个生命周期内保持不变,如存储定时器ID、表单元素引用等。

8. useImperativeHandle

  • 参数
    • 第一个参数:一个ref对象,通常是通过useRef创建的。
    • 第二个参数:一个函数,用于定义暴露给父组件的实例值。
    • 第三个参数(可选):依赖项数组,用于指定什么时候重新定义暴露的值。
  • 应用实例
import React, { forwardRef, useImperativeHandle, useState } from 'react';
const Child = forwardRef((props, ref) => {
    const [count, setCount] = useState(0);
    useImperativeHandle(ref, () => ({
        increment: () => setCount(count + 1)
    }));
    return <div>{count}</div>;
});
function Parent() {
    const childRef = useRef();
    const handleClick = () => {
        childRef.current.increment();
    };
    return (
        <>
            <Child ref={childRef} />
            <button onClick={handleClick}>Increment Child</button>
        </>
    );
}
  • 应用场景
    • 用于在使用forwardRef的情况下,自定义暴露给父组件的子组件实例属性和方法。

9. useLayoutEffect

  • 参数和使用方式类似useEffect
    • 区别在于useLayoutEffect会在所有DOM变更之后同步调用,在浏览器进行绘制之前。而useEffect是在浏览器绘制之后异步调用。
  • 应用场景
    • 当需要在DOM更新后立即读取布局信息并进行同步操作时使用,如获取更新后的DOM元素的位置、尺寸等信息。

10. useDebugValue

  • 参数
    • 第一个参数:要在React开发者工具中显示的值。
    • 第二个参数(可选):一个格式化函数,用于格式化显示的值。
  • 应用场景
    • 用于在React开发者工具中为自定义Hook提供调试信息,方便开发者查看Hook的内部状态。

React渲染更新原理

1. 虚拟DOM(Virtual DOM)

  • React会根据组件的状态和属性构建一个虚拟DOM树。虚拟DOM是一个轻量级的JavaScript对象,它描述了真实DOM应该是什么样子。例如,一个简单的React组件:
function MyComponent() {
    return <div><p>Hello</p></div>;
}

对应的虚拟DOM可能是类似这样的结构:

{
    type: 'div',
    props: {
        children: [
            {
                type: 'p',
                props: {
                    children: 'Hello'
                }
            }
        ]
    }
}
  • 当组件的状态或属性发生变化时,React会重新构建一个新的虚拟DOM树。

2. 协调(Reconciliation)

  • React使用diff算法来比较新旧虚拟DOM树。这个算法有一些优化策略,例如:
    • 不同类型的元素:如果元素类型改变(如从<div>变为<span>),React会认为整个子树都改变了,会销毁旧的DOM节点并创建新的DOM节点。
    • 同类型的元素:React会比较它们的属性和子元素。对于属性,只会更新变化的属性;对于子元素,会采用高效的比较算法来最小化DOM操作。
  • 例如,有以下组件更新:
function MyComponent() {
    const [count, setCount] = useState(0);
    return (
        <div>
            <p>{count}</p>
            <button onClick={() => setCount(count + 1)}>Increment</button>
        </div>
    );
}

count状态改变时,React会构建新的虚拟DOM,比较新旧虚拟DOM,发现<p>标签的内容发生了变化,只会更新<p>标签的文本内容,而不会重新创建整个div和按钮。

3. 批量更新和DOM操作

  • React会根据diff的结果,计算出最小的DOM操作集合,然后批量更新真实DOM。这样可以减少浏览器重排(reflow)和重绘(repaint)的次数,提高性能。例如,在一次更新中如果有多个组件状态变化导致DOM更新,React会将这些更新合并,一次性应用到真实DOM上。

React Hook函数的运行调用

  • Hook函数必须在函数组件的顶层调用。这是为了保证Hook的调用顺序在每次组件渲染时都是一致的。例如,下面是错误的调用方式:
function MyComponent() {
    if (someCondition) {
        const [count, setCount] = useState(0);
    }
    //...
}
  • 每次组件重新渲染时,Hook函数会按照它们在组件中定义的顺序重新执行。React内部通过一个链表结构来管理Hook。在函数组件内部,有一个隐藏的状态指针,每次调用Hook函数时,这个指针会移动到下一个Hook节点。当组件重新渲染时,这个指针又会从头开始,按照相同的顺序调用Hook,从而保证状态的正确更新和副作用的正确执行。

React实现MVVM

  • Model(数据层)
    • 在React中,stateprops可以看作是模型的一部分。state用于存储组件内部的状态,props用于接收外部传入的数据。例如,在一个用户信息展示组件中,state可能存储用户的编辑状态(如是否处于编辑模式),props可能接收用户的基本信息(如姓名、年龄等)。
  • View(视图层)
    • React组件的JSX部分可以看作是视图。它根据stateprops来渲染出用户界面。例如,一个简单的列表组件:
function ListComponent({ items }) {
    return (
        <ul>
            {items.map((item) => (
                <li key={item.id}>{item.name}</li>
            ))}
        </ul>
    );
}

这里itemspropsJSX代码根据items渲染出一个无序列表视图。

  • ViewModel(数据 - 视图绑定层)
    • 在React中,useStateuseEffect等Hook函数可以看作是数据 - 视图绑定的工具。useState用于将state和视图绑定,当state改变时,视图会重新渲染。useEffect可以用于在stateprops变化时执行副作用操作,间接影响视图。例如:
function Counter() {
    const [count, setCount] = useState(0);
    useEffect(() => {
        document.title = `Count: ${count}`;
    }, [count]);
    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={() => setCount(count + 1)}>Increment</button>
        </div>
    );
}

这里useState绑定了count状态和视图中的显示内容,useEffectcount变化时更新文档标题,实现了数据 - 视图的双向绑定。

技术细节( useEffect 清理监听事件和 定时器)

  1. 清理监听事件

    • useEffect中返回一个清理函数来处理事件监听器的清理。当组件卸载或者useEffect的依赖项发生变化重新执行时,这个清理函数会被调用。
    • 例如,当组件挂载时添加一个windowresize事件监听器,在组件卸载或者依赖项变化时需要移除这个监听器,以避免内存泄漏。
    • 以下是一个示例代码:
    import React, { useState, useEffect } from 'react';
    
    function ResizeComponent() {
        const [windowWidth, setWindowWidth] = useState(window.innerWidth);
    
        useEffect(() => {
            const handleResize = () => {
                setWindowWidth(window.innerWidth);
            };
            window.addEventListener('resize', handleResize);
            // 返回清理函数,用于移除事件监听器
            return () => {
                window.removeEventListener('resize', handleResize);
            };
        }, []);
    
        return (
            <div>
                <p>当前窗口宽度: {windowWidth}px</p>
            </div>
        );
    }
    
    export default ResizeComponent;
    
    • 在这个示例中,useEffect的第一个参数是一个函数,在这个函数内部添加了windowresize事件监听器handleResize。这个监听器会在window大小改变时更新windowWidth状态,从而更新组件的显示内容。useEffect的第二个参数是一个空数组[],这意味着这个effect只会在组件挂载和卸载时执行一次。返回的清理函数return () => { window.removeEventListener('resize', handleResize); }用于在组件卸载或者依赖项改变重新执行useEffect时移除resize事件监听器。
  2. 清理定时器

    • 同样是在useEffect中返回一个清理函数来处理定时器的清除。
    • 例如,设置一个定时器每隔一秒更新一次计数器的值,当组件卸载或者依赖项变化重新执行useEffect时,需要清除这个定时器,以防止定时器继续运行导致内存泄漏或者其他错误。
    • 以下是一个示例代码:
    import React, { useState, useEffect } from 'react';
    
    function TimerComponent() {
        const [count, setCount] = useState(0);
    
        useEffect(() => {
            const timer = setInterval(() => {
                setCount((prevCount) => prevCount + 1);
            }, 1000);
            // 返回清理函数,用于清除定时器
            return () => {
                clearInterval(timer);
            };
        }, []);
    
        return (
            <div>
                <p>计数器: {count}</p>
            </div>
        );
    }
    
    export default TimerComponent;
    
    • 在这个示例中,useEffect内部通过setInterval创建了一个定时器,每隔一秒会更新count状态。返回的清理函数return () => { clearInterval(timer); }用于在组件卸载或者依赖项改变重新执行useEffect时清除这个定时器。

diff算法

  1. Diff算法的目的

    • React的Diff算法主要用于比较新旧虚拟DOM树,以确定最小的DOM操作集合来更新真实DOM。由于直接操作真实DOM的性能开销较大,Diff算法的高效性有助于减少不必要的DOM操作,如重排(reflow)和重绘(repaint),从而提高应用的性能。
  2. 分层比较策略

    • React将虚拟DOM树按照层级进行比较。比较从树的根节点开始,递归地对每个层级的节点进行比较。
    • 例如,有一个简单的组件树结构如下:
    <div>
        <p>Hello</p>
        <span>World</span>
    </div>
    
    • React会先比较最外层的div节点,然后再比较div节点下的pspan子节点。
  3. 不同类型元素的比较

    • 当发现新旧虚拟DOM树中节点的类型不同时,React会认为该节点及其子节点完全不同。
    • 例如,旧的节点是<div>,新的节点是<span>,React会销毁旧的div节点及其所有子节点,然后创建新的span节点及其子节点。
    • 假设原来的组件是这样的:
    function OldComponent() {
        return <div><p>Old Content</p></div>;
    }
    
    • 现在更新为:
    function NewComponent() {
        return <span><p>New Content</p></span>;
    }
    
    • React会直接替换整个DOM结构,因为根节点的类型从div变成了span
  4. 同类型元素的比较

    • 对于相同类型的元素,React会比较它们的属性。只有属性发生变化的部分才会更新到真实DOM上。
    • 例如,有一个<input>元素,旧的属性是{type: "text", value: "old value"},新的属性是{type: "text", value: "new value"},React会只更新value属性,而不会重新创建整个input元素。
    • 假设组件中有一个输入框:
    function InputComponent() {
        const [value, setValue] = useState('Initial');
        useEffect(() => {
            setTimeout(() => {
                setValue('Updated');
            }, 1000);
        }, []);
        return <input type="text" value={value} />;
    }
    
    • 在这里,当value状态更新时,React会比较新旧input元素(因为类型相同),然后只更新value属性。

    • 同时,对于同类型元素的子节点,React会采用高效的比较策略。如果子节点是列表形式,React会使用key属性来帮助识别每个子节点。

    • 例如,有一个列表组件:

    function ListComponent() {
        const [items, setItems] = useState(['a', 'b', 'c']);
        useEffect(() => {
            setTimeout(() => {
                setItems(['b', 'c', 'd']);
            }, 1000);
        }, []);
        return (
            <ul>
                {items.map((item, index) => (
                    <li key={index}>{item}</li>
                ))}
            </ul>
        );
    }
    
    • 在这个例子中,当items数组更新时,React会根据key(这里使用了索引index,但在实际应用中最好使用唯一标识符)来比较每个li子节点。如果key相同,就比较节点内容;如果key不同,就认为是新的节点或者旧节点被删除了。不过,使用索引作为key可能会导致性能问题和错误的更新行为,在可能的情况下,最好使用数据的唯一标识符作为key
  5. Diff算法的优化措施

    • React的Diff算法基于一些假设和优化策略来提高性能。例如,它假设在同一层级上,节点的顺序和类型不会频繁地、大幅度地变化。这种假设使得React可以采用简单而高效的比较策略。
    • 同时,React会尽量复用已有的DOM节点。当节点可以复用(类型相同且大部分属性相同)时,就不会重新创建DOM节点,而是更新节点的属性和内容。这有助于减少DOM操作的数量,从而提高应用的整体性能。

react 父子组件生命周期应用及渲染

  1. 挂载阶段(Mounting)

    • 父组件挂载
      • 当一个React应用启动时,首先会挂载根组件。在挂载过程中,父组件的constructor(如果是类组件)会被调用,用于初始化组件的状态和绑定事件处理函数等。
      • 例如,一个简单的父组件ParentComponent
      import React, { Component } from 'react';
      import ChildComponent from './ChildComponent';
      class ParentComponent extends Component {
          constructor(props) {
              super(props);
              this.state = {
                  parentData: 'Initial Parent Data'
              };
          }
          componentDidMount() {
              console.log('Parent Component Mounted');
          }
          render() {
              return (
                  <div>
                      <ChildComponent parentData={this.state.parentData} />
                  </div>
              );
          }
      }
      export default ParentComponent;
      
      • constructor中初始化了parentData状态,然后在componentDidMount生命周期方法中打印出Parent Component Mounted,这个方法会在组件挂载到DOM后被调用,常用于进行数据获取、订阅事件等操作。
    • 子组件挂载
      • 当父组件的render方法返回包含子组件的JSX时,子组件开始挂载。子组件同样会经历constructor(如果是类组件)初始化过程。
      • 例如,ChildComponent
      import React, { Component } from 'react';
      class ChildComponent extends Component {
          constructor(props) {
              super(props);
              console.log('Child Constructor');
          }
          componentDidMount() {
              console.log('Child Component Mounted');
          }
          render() {
              return (
                  <div>
                      <p>{this.props.parentData}</p>
                  </div>
              );
          }
      }
      export default ChildComponent;
      
      • constructor中会打印Child Constructor,用于初始化子组件相关的操作。componentDidMount方法会在子组件挂载到DOM后被调用,这里会打印Child Component Mounted
    • 挂载顺序总结
      • 挂载顺序是先父组件的constructor,然后是父组件的render,在父组件render过程中如果有子组件,会先调用子组件的constructor,最后是子组件的componentDidMount,再是父组件的componentDidMount。在上述例子中,控制台输出顺序是:Child Constructor -> Child Component Mounted -> Parent Component Mounted
  2. 更新阶段(Updating)

    • 父组件更新
      • 当父组件的状态或属性发生变化时,父组件会重新渲染。在更新过程中,shouldComponentUpdate(如果定义了这个方法)会首先被调用,用于决定组件是否需要更新。
      • 例如,在ParentComponent中添加一个更新状态的方法:
      import React, { Component } from 'react';
      import ChildComponent from './ChildComponent';
      class ParentComponent extends Component {
          constructor(props) {
              super(props);
              this.state = {
                  parentData: 'Initial Parent Data'
              };
          }
          componentDidMount() {
              console.log('Parent Component Mounted');
          }
          updateParentData = () => {
              this.setState({
                  parentData: 'Updated Parent Data'
              });
          };
          render() {
              return (
                  <div>
                      <button onClick={this.updateParentData}>Update Parent Data</button>
                      <ChildComponent parentData={this.state.parentData} />
                  </div>
              );
          }
      }
      export default ParentComponent;
      
      • 当点击Update Parent Data按钮时,parentData状态更新,shouldComponentUpdate(如果有)会被调用。如果这个方法返回true(默认行为),组件会继续更新。
    • 子组件更新
      • 因为父组件的状态或属性变化导致子组件的props变化,子组件也会更新。子组件会先调用componentWillReceiveProps(如果是类组件且定义了这个方法)来接收新的props,然后根据新的props进行更新。
      • 对于ChildComponent,如果定义componentWillReceiveProps方法可以这样:
      import React, { Component } from 'react';
      class ChildComponent extends ClassComponent {
          constructor(props) {
              super(props);
              console.log('Child Constructor');
          }
          componentWillReceiveProps(nextProps) {
              console.log('Child Will Receive Props');
              console.log('Old Props:', this.props);
              console.log('New Props:', nextProps);
          }
          componentDidUpdate(prevProps, prevState) {
              console.log('Child Component Updated');
              console.log('Previous Props:', prevProps);
              console.log('Current Props:', this.props);
          }
          render() {
              return (
                  <div>
                      <p>{this.props.parentData}</p>
                  </div>
              );
          }
      }
      export default ChildComponent;
      
      • 当父组件更新导致子组件props变化时,componentWillReceiveProps会被调用,用于处理新的props。然后componentDidUpdate会在子组件更新完成后被调用,用于执行更新后的操作,如检查props或状态的变化情况。
    • 更新顺序总结
      • 当父组件状态或属性更新导致子组件props更新时,更新顺序一般是父组件的shouldComponentUpdate(如果有) -> 父组件的render -> 子组件的componentWillReceiveProps(如果有) -> 子组件的render -> 子组件的componentDidUpdate -> 父组件的componentDidUpdate
  3. 卸载阶段(Unmounting)

    • 子组件卸载

      • 当父组件的render方法不再返回某个子组件时,子组件会被卸载。此时,子组件的componentWillUnmount方法会被调用,用于清理在组件挂载和使用过程中产生的副作用,如清除定时器、取消事件订阅等。
      • 例如,在ParentComponent中添加一个条件渲染,使得ChildComponent可以被卸载:
      import React, { Component } from 'react';
      import ChildComponent from './ChildComponent';
      class ParentComponent extends Component {
          constructor(props) {
              super(props);
              this.state = {
                  showChild: true
              };
          }
          componentDidMount() {
              console.log('Parent Component Mounted');
          }
          toggleChild = () => {
              this.setState((prevState) => ({
                  showChild:!prevState.showChild
              }));
          };
          render() {
              return (
                  <div>
                      <button onClick={this.toggleChild}>Toggle Child</button>
                      {this.state.showChild && <ChildComponent parentData={this.state.parentData} />}
                  </div>
              );
          }
      }
      export default ParentComponent;
      
      • ChildComponent中添加componentWillUnmount方法:
      import React, { Component } from 'react';
      class ChildComponent extends Component {
          constructor(props) {
              super(props);
              console.log('Child Constructor');
          }
          componentWillUnmount() {
              console.log('Child Component Unmounted');
          }
          render() {
              return (
                  <div>
                      <p>{this.props.parentData}</p>
                  </div>
              );
          }
      }
      export default ChildComponent;
      
      • 当点击Toggle Child按钮,showChild状态改变导致ChildComponent被卸载时,会打印Child Component Unmounted
    • 父组件卸载

      • 当整个应用或者包含父组件的上级组件被卸载时,父组件的componentWillUnmount方法也会被调用,用于清理父组件相关的副作用。
    • 卸载顺序总结

      • 先卸载子组件,调用子组件的componentWillUnmount,然后如果父组件也被卸载,再调用父组件的componentWillUnmount

标签:count,React,return,DOM,react,hook,props,组件,diff
From: https://blog.csdn.net/m0_51244077/article/details/143260309

相关文章

  • 使用AMD GPU和ONNX Runtime高效生成图像与Stable Diffusion模型
    EfficientimagegenerationwithStableDiffusionmodelsandONNXRuntimeusingAMDGPUs2024年2月23日撰写,作者[道格拉斯·贾(DouglasJia)](DouglasJia—ROCmBlogs)在这篇博客中,我们将向您展示如何使用预训练的StableDiffusion模型,通过ONNXRuntime在AMDGPU上生成......
  • 刚刚,Stable Diffusion 2024升级,最强Ai绘画整合包、部署教程(解压即用)
    2024Ai技术大爆发的元年目前两款Ai神器大火一款是大名鼎鼎的ChatGPT另外一款—StableDiffusion堪称全球最强Ai绘画工具StableDiffusionAi绘画2024版本更新啦!从4.8.7更新至**4.9版本!**更新优化和大模型增加,无需安装,解压即用sd整合包获取方式Stablediffusion......
  • react数组插入
    1、定义数组:const[items,setItems]=useState([]);2、普通js写法插入:setItems([...items,newItem])但是由于react是异步渲染的,这种更新方式可能会导致渲染不同步3、推荐更新方式:使用setState方法,并提供一个函数,该函数接收先前的状态,并返回一个更新后的状态。constaddIte......
  • Diffusion Probabilistic Models for 3D Point Cloud Generation——点云论文阅读(8)
    此内容是论文总结,重点看思路!!文章概述该文献介绍了一种用于3D点云生成的概率模型。点云是表示3D物体和场景的常用方式,但由于其不规则的采样模式,与图像相比,点云生成更具挑战性。现有方法如GANs、流模型和自回归模型在点云生成方面取得了进展,但它们在训练稳定性、生成顺序假设和......
  • Stable Diffusion 3.5 正式发布!免费开源,堪称最强AI文生图模型,附本地安装和在线使用教
    关键要点:10月22日,stability.ai重磅推出StableDiffusion3.5,号称迄今为止最强大的文生图模型。此次公开版本包括多个模型变体,其中有StableDiffusion3.5Large和StableDiffusion3.5LargeTurbo。此外,StableDiffusion3.5Medium将于10月29日发布。这些模型在尺......
  • kube-prometheus-stack 自定义 alertmanager 配置推送webhook
    创建AlertmanagerConfig资源在没有使用prometheus-operator的情况下,需要手动配置alertmanager.yaml来路由&发送从prometheus接收的警报。使用prometheus-operator之后,事情变得简单一些。只需要创建AlertmanagerConfig资源,prometheus-operator会自动merge所有的Ale......
  • Zustand介绍与使用 React状态管理工具
    文章目录前言基本使用编写状态加方法在组件中使用异步方法操作中间件简化状态获取优化性能持久化保存前言在现代前端开发中,状态管理一直是一个关键的挑战。随着应用规模的扩大,组件间的状态共享变得愈加复杂。为了应对这一需求,开发者们逐渐寻找更加轻量、灵活的......
  • 了解React Native应用中的createNativeStackNavigator 组件
    createNativeStackNavigator是ReactNavigation库中的一个组件,专门用于在ReactNative应用中创建原生的堆栈导航器(StackNavigator)。这个组件允许你在应用中实现页面之间的导航,如从主页面跳转到详情页面,然后再返回主页面。与传统的JavaScript堆栈导航器相比,createNat......
  • 尚硅谷-react教程-求和案例-数据共享(下篇)-完成数据共享-笔记
    #1024程序员节|征文# public/index.html<!DOCTYPEhtml><html><head><metacharset="UTF-8"><title>redux</title></head><body><divid="root"><......
  • React--》掌握Valtio让状态管理变得轻松优雅
    Valtio采用了代理模式,使状态管理变得更加直观和易于使用,同时能够与React等框架无缝集成,本文将深入探讨Valtio的核心概念、使用场景以及其在提升应用性能中的重要作用,帮助你掌握这一强大工具,从而提升开发效率和用户体验。目录初识ValtioValtio基础使用代理与快照订阅与侦......