React Hooks 详细使用介绍

useState 状态管理

useState 是 React 中的一个基础 Hook,允许你在不使用 class 组件的情况下管理组件状态。

参数

初始值

你可以直接传递状态的初始值给 useState

const [name, setName] = useState("John");

使用函数设置初始值

当初始化状态代价较大时,你可以传递一个函数:

const [state, setState] = useState(() => {const initialState = calculateInitialState(); // 一些复杂的操作return initialState;
});

返回值

useState 返回一个数组,其中包括当前状态值和一个更新状态的函数。

示例

基础计数器示例

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)}>Increment</button><button onClick={() => setCount(count - 1)}>Decrement</button></div>);
}

使用对象作为状态

function UserProfile() {const [profile, setProfile] = useState({ name: "John", age: 30 });const updateName = name => {setProfile(prevProfile => ({ ...prevProfile, name }));};return (<div><p>Name: {profile.name}</p><p>Age: {profile.age}</p><button onClick={() => updateName("Doe")}>Update Name</button></div>);
}

使用多个 useState

你可以在一个组件中使用多个 useState 来管理不同的状态片段:

function MultiCounter() {const [count1, setCount1] = useState(0);const [count2, setCount2] = useState(0);return (<div><p>Counter 1: {count1}</p><button onClick={() => setCount1(count1 + 1)}>Increment Counter 1</button><p>Counter 2: {count2}</p><button onClick={() => setCount2(count2 + 1)}>Increment Counter 2</button></div>);
}

注意事项

  • 调用位置:在 React 函数的最顶层调用 useState

  • 依赖之前的状态更新:使用函数式更新,如:setCount(prevCount => prevCount + 1)

  • 不会自动合并对象:手动合并对象,如:setState(prevState => ({ ...prevState, key: 'value' }))

useEffect 副作用操作

React 函数组件的副作用利器

什么是副作用?

在编程中,副作用是指代码对外部世界产生的影响。比如说,你想在用户点击按钮后改变网页的标题。这个改变就是一个副作用。

为什么需要 useEffect

React 组件通常用于渲染 UI,但有时你还需要执行一些额外的操作,如网络请求、操作 DOM 或订阅事件等。这些操作就是所谓的副作用,而 useEffect 就是用来处理这些副作用的工具。

如何使用 useEffect

useEffect 的使用很简单。它接受两个参数:一个副作用函数和一个依赖数组。

  • 副作用函数:放置你想执行的副作用代码。
  • 依赖数组:决定副作用何时执行。数组中的值发生变化时,副作用会重新执行。

例子

改变网页标题

假设你想在组件挂载后改变网页标题。你可以这样做:

useEffect(() => {document.title = "新的标题";
}, []); // 空数组表示只在组件挂载后执行一次
获取用户数据

如果你想根据用户 ID 获取用户数据,你可以这样做:

function UserProfile({ userId }) {const [user, setUser] = useState(null);useEffect(() => {fetch(`/api/user/${userId}`).then(response => response.json()).then(setUser);}, [userId]); // 当 userId 改变时,重新获取数据
}

注意事项

  • 清理副作用:如果你的副作用涉及需要清理的操作(例如取消订阅事件),你可以在副作用函数中返回一个清理函数。

    useEffect(() => {const timerId = setInterval(() => {console.log("Tick");}, 1000);return () => {clearInterval(timerId); // 清理定时器};
    }, []);
    
  • 避免无限循环:不小心使用 useEffect 可能导致无限循环。务必注意你的依赖数组,确保副作用按预期执行。

useMemo 记忆计算值

useMemo 钩子用于在组件渲染期间记住复杂计算的结果。这可以提高性能,尤其是当有大量计算和重新计算时。

为什么使用 useMemo

当组件重新渲染时,可能会涉及到一些复杂的计算。如果这些计算的依赖项没有改变,那么重新进行这些计算就是浪费。useMemo 允许你记住这些计算的结果,只有当依赖项改变时才重新计算。

如何使用 useMemo

useMemo 接受两个参数:一个函数和一个依赖项数组。它会返回该函数的返回值。

  • 函数:包含要记住的计算。
  • 依赖项数组:当数组中的任何值发生变化时,函数将被重新执行。

TypeScript 示例代码

下面的示例展示了如何使用 useMemo 来过滤大于 10 的数字。只有当数字数组改变时,才会重新计算过滤的结果。

import React, { useMemo, useState } from "react";interface Props {items: number[];
}const ExpensiveComponent: React.FC<Props> = ({ items }) => {const filteredItems = useMemo(() => items.filter(item => item > 10), [items]);return (<div><h3>Filtered Items (Greater than 10):</h3>{filteredItems.map(item => (<div key={item}>{item}</div>))}</div>);
};const App: React.FC = () => {const [items, setItems] = useState<number[]>([5, 12, 8, 20, 33]);const addItem = () => setItems([...items, Math.floor(Math.random() * 40)]);return (<div><button onClick={addItem}>Add Item</button><h3>All Items:</h3>{items.map(item => (<div key={item}>{item}</div>))}<ExpensiveComponent items={items} /></div>);
};export default App;

注意事项

  • 不要将 useMemo 作为性能优化的首要工具。除非你确实遇到性能问题,并且确定了 useMemo 可以解决问题,否则不要过早优化。
  • 不应该在 useMemo 的函数内部执行有副作用的操作。使用 useEffect 处理副作用。

总结

useMemo 是一个非常强大的工具,可以提高组件的性能,尤其是在复杂的计算和频繁的重新渲染中。但是,也要谨慎使用它,确保只在确实需要时使用它,并始终确保你的代码的正确性和可维护性。

useCallback :记忆化函数

什么是 useCallback

useCallback 用于在组件的连续渲染之间记忆化(或缓存)函数。它帮助避免因父组件重新渲染而导致的不必要的子组件渲染。

如何使用?

useCallback 接受两个参数:一个函数和一个依赖数组。只有当依赖数组中的值发生变化时,函数才会被重新创建。

示例

让我们看一个完整的示例,展示如何使用 useCallback 来优化组件的渲染。

import React, { useState, useCallback } from "react";const ChildComponent = React.memo(({ onClick }) => {console.log("ChildComponent re-rendered!");return <button onClick={onClick}>Click Me!</button>;
});function ParentComponent() {const [count, setCount] = useState(0);// 使用 useCallback 记忆化 handleClick 函数const handleClick = useCallback(() => {console.log("Button was clicked");}, []); // 空依赖数组,表示该函数不会重新创建return (<div><h1>{count}</h1><button onClick={() => setCount(count + 1)}>Increment Counter</button>{/* 传递记忆化的 handleClick 到 ChildComponent */}<ChildComponent onClick={handleClick} /></div>);
}export default ParentComponent;

在上面的示例中,ChildComponent 接受一个 onClick 属性,并且使用 React.memo 进行了优化,所以只有当 onClick 属性发生变化时才会重新渲染。由于 handleClick 使用 useCallback 被记忆化了,因此即使父组件重新渲染,handleClick 函数也不会更改,从而避免了子组件的不必要渲染。

注意事项

  1. 过度优化的风险:不是所有的函数都需要使用 useCallback。如果一个函数没有传递给子组件或其他记忆化操作,使用 useCallback 可能会带来更多的复杂性和性能开销。
  2. 依赖项的准确性:确保依赖数组中的所有值都是必需的,并且当它们发生变化时,你确实希望函数被重新创建。

总结

useCallback 是一个强大的优化工具,可以在适当的情况下提高 React 组件的性能。通过使用此 Hook,你可以控制函数的重新创建,从而避免因父组件重新渲染而导致的不必要的子组件渲染。

该示例展示了如何在实际组件中使用 useCallback 进行优化,希望这有助于你更深入地理解这个 Hook 的用途和工作方式。如果你有任何问题或需要进一步的解释,请随时提问!

useCallback 和 useMemo 区别

  • 用途useCallback 用于记忆化函数,而 useMemo 用于记忆化计算值。
  • 返回值useCallback 返回一个记忆化的函数;useMemo 返回一个记忆化的计算结果。
  • 最佳实践
    • 当你需要传递给子组件的函数并希望避免不必要的子组件渲染时,使用 useCallback
    • 当你有昂贵的计算,并希望在依赖项未更改时避免重新计算时,使用 useMemo

useRef 访问 Ref

用于访问和操作 DOM 元素及保持可变的引用值

什么是 useRef

useRef Hook 用于访问和操作 DOM 元素,并在组件的整个生命周期中保持不变的引用。除了用于直接操作 DOM,useRef 还可用于在组件的不同渲染之间保留可变的引用值,而不触发重新渲染。

如何使用 useRef

要使用 useRef,你首先需要调用它,并将初始值作为参数传递(如果有)。这将返回一个 ref 对象,该对象具有一个名为 current 的属性,该属性将引用传递给 useRef 的初始值或 DOM 元素。

使用 useRef 访问 DOM 元素

你可以使用 useRef 直接访问和操作 DOM 元素。下面是一个示例,显示了如何使用 useRef 控制输入元素的焦点。

import React, { useRef } from "react";function TextInput() {const inputRef = useRef(null);const handleFocus = () => {inputRef.current.focus(); // 使用 ref 对象的 current 属性访问输入元素};return (<div><input ref={inputRef} type="text" /><button onClick={handleFocus}>Focus the input</button></div>);
}

在上述示例中,我们创建了一个 ref 对象并将其分配给输入元素。然后,我们可以使用该引用在按钮点击时将焦点设置到输入元素上。

使用 useRef 保留可变的引用值

除了用于访问 DOM 元素外,useRef 还可以用于在组件的连续渲染之间保留可变的引用值,而不触发重新渲染。

import React, { useRef, useEffect } from "react";function Timer() {const countRef = useRef(0);useEffect(() => {const intervalId = setInterval(() => {countRef.current += 1; // 更新 ref 的 current 值console.log("Timer:", countRef.current);}, 1000);return () => clearInterval(intervalId); // 清除计时器}, []); // 空依赖数组表示该效果只在挂载和卸载时运行return <div>Check the console to see the timer count!</div>;
}

在这个示例中,我们使用 useRef 来保持计时器的计数值。因为 ref 对象的更改不会触发组件的重新渲染,所以它是一个非常有用的工具,用于在重新渲染之间保留值。

总结

useRef 是一个多功能的 React Hook,可以用于多种用途:

  • 访问和操作 DOM 元素:使用 ref 对象的 current 属性直接访问和操作 DOM 元素。
  • 保留可变引用值:在组件的不同渲染之间保留值,而不触发重新渲染。

自定义组件使用 Ref

在 React 中,你可以使用引用(ref)与自定义组件进行交互,访问组件的实例。这是一个非常有用的特性,可以用于获取组件内部的信息,调用组件内部的方法,或者与组件进行更复杂的交互。

使用 forwardRef 与自定义组件

对于自定义组件,你通常需要使用 forwardRef 来转发 ref。下面是一个简单的示例,显示如何使用 forwardRef 创建自定义组件,并从父组件中访问该组件的 DOM 元素:

import React, { useRef, forwardRef } from "react";const CustomComponent = forwardRef((props, ref) => {return <div ref={ref}>Custom Component</div>;
});function App() {const customComponentRef = useRef(null);const handleClick = () => {customComponentRef.current.style.backgroundColor = "lightblue";};return (<div><CustomComponent ref={customComponentRef} /><button onClick={handleClick}>Change Background Color</button></div>);
}export default App;

使用 useImperativeHandle 暴露自定义实例属性

有时,你可能希望自定义组件能够暴露特定的实例方法或属性给父组件。在这种情况下,你可以使用 useImperativeHandle 进行更精细的控制。下面的示例显示了如何使用 useImperativeHandle 暴露组件的特定方法:

import React, { useRef, forwardRef, useImperativeHandle } from "react";const CustomComponent = forwardRef((props, ref) => {useImperativeHandle(ref, () => ({sayHello: () => {alert("Hello from CustomComponent!");},}));return <div>Custom Component</div>;
});function App() {const customComponentRef = useRef(null);const handleClick = () => {customComponentRef.current.sayHello(); // 调用自定义组件的方法};return (<div><CustomComponent ref={customComponentRef} /><button onClick={handleClick}>Say Hello</button></div>);
}export default App;

总结

与自定义组件一起使用 ref 可以实现许多强大的功能,从访问组件内部的 DOM 元素,到调用组件的特定实例方法。通过使用 forwardRefuseImperativeHandle,你可以更灵活地控制自定义组件的行为,并与之进行更复杂的交互。

请注意,直接操作 DOM 和组件实例通常应该作为最后的手段,因为它可能会导致代码难以理解和维护。在可能的情况下,尽量使用正常的 React 数据流来管理组件的状态和行为。

useContext 访问上下文

useContext 钩子是 React 中一个非常强大的工具,用于在组件树中跨层级共享状态。它消除了通过多层组件手动传递 props 的需要,使得状态管理变得更加清晰和高效。

为什么使用 useContext

在复杂的 React 应用程序中,状态需要在多个组件之间共享。传统方法是将状态作为 props 从顶层组件一层一层传递下去,但这会导致代码混乱且难以维护。useContext 允许我们跨越组件层级直接共享状态,无需手动传递。

如何使用 useContext

  1. 创建上下文: 使用 React 的 createContext 方法创建一个上下文。

  2. 提供上下文: 使用 Context.Provider 组件在组件树中提供上下文的值。

  3. 消费上下文: 在任何子组件中使用 useContext 钩子访问上下文的值。

TypeScript 示例代码

下面的示例展示了如何使用 useContext 来共享主题设置。

import React, { useContext, useState } from "react";// 创建上下文
const ThemeContext = React.createContext<{ theme: string; toggleTheme: () => void } | undefined>(undefined);const App: React.FC = () => {const [theme, setTheme] = useState("light");const toggleTheme = () => {setTheme(theme === "light" ? "dark" : "light");};// 提供上下文return (<ThemeContext.Provider value={{ theme, toggleTheme }}><Header /><MainContent /></ThemeContext.Provider>);
};const Header: React.FC = () => {// 消费上下文const themeContext = useContext(ThemeContext);if (!themeContext) {return <h1>Error: Theme not found</h1>;}return (<div><h1>{themeContext.theme} theme is active</h1><button onClick={themeContext.toggleTheme}>Toggle Theme</button></div>);
};const MainContent: React.FC = () => {// ...return <div>Main Content</div>;
};export default App;

注意事项

  • 确保在使用 useContext 之前已经在组件树中提供了上下文。
  • 不要在渲染过程中更改上下文的值,这可能会导致组件的不必要重新渲染。

总结

useContext 钩子是一个强大的工具,用于组件之间的跨层级状态共享。通过消除手动传递 props 的需要,它可以使你的代码更加清晰、简洁,同时也提高了代码的可维护性。

useReducer 复杂状态逻辑

useReducer 是 React 中用于处理组件状态逻辑的钩子,尤其适用于更复杂或包括多个子值的状态。它的工作原理类似于 Redux,但是更加精简,不需要引入额外的库。

为什么使用 useReducer

当状态逻辑复杂或者下一状态依赖于之前的状态时,useReducer 非常有用。相较于 useState,它提供了更可预测的状态更新方式,并且更容易测试和维护。

如何使用 useReducer

useReducer 接收两个参数:一个 reducer 函数和初始状态,返回当前状态和一个 dispatch 函数。

  1. Reducer 函数: 这个函数接收两个参数:当前的状态和一个动作。根据动作类型,它返回一个新的状态。

  2. 初始状态: 初始状态是 reducer 的第一个参数的初始值。

  3. Dispatch 函数: 这个函数用于分派动作,触发 reducer 函数,并更新状态。

TypeScript 示例代码

下面的示例演示了如何使用 useReducer 来管理一个计数器的状态。

import React, { useReducer } from "react";// 定义动作类型
type Action = { type: "increment" } | { type: "decrement" };// 定义reducer函数
const counterReducer = (state: number, action: Action) => {switch (action.type) {case "increment":return state + 1;case "decrement":return state - 1;default:return state;}
};const Counter: React.FC = () => {// 使用useReducerconst [state, dispatch] = useReducer(counterReducer, 0);return (<div><h1>Count: {state}</h1><button onClick={() => dispatch({ type: "increment" })}>Increment</button><button onClick={() => dispatch({ type: "decrement" })}>Decrement</button></div>);
};export default Counter;

注意事项

  • Reducer 必须是一个纯函数,这意味着同样的输入必须产生相同的输出,不应有副作用。
  • 尽量使 reducer 函数保持简洁明了,可以通过拆分成多个子 reducer 来处理更复杂的状态逻辑。

总结

useReducer 钩子提供了一种更灵活、可维护的方式来处理复杂的状态逻辑。通过结合纯净的 reducer 函数和动作分派,它为开发人员提供了对组件内部状态更细粒度的控制。对于需要管理复杂状态或者希望与 Redux 保持一致的项目,useReducer 是一个极好的选择。

useImperativeHandle 自定义 ref 暴露

useImperativeHandle 是一种特殊的钩子,允许你在父组件中直接操作子组件中的某些实例方法。通常来说,在 React 中,组件应该遵循数据自上而下的流动,并通过属性和状态进行通信。但有时,你可能需要在父组件中直接调用子组件的某些方法。这就是 useImperativeHandle 发挥作用的地方。

这个钩子不常用,因为它打破了 React 的一些核心原则,但在某些特定场景下可能很有用。

参数

useImperativeHandle 接受三个参数:

  1. ref: 父组件传递给子组件的 ref 对象。
  2. createHandle: 一个返回包含暴露给父组件的实例方法的对象的函数。
  3. deps: 一个依赖数组,类似于 useEffectuseMemo 等钩子。如果提供了此参数,则只有当依赖项更改时,才会更新实例方法。

示例

假设你有一个 TextInput 组件,并且你想暴露一个方法来清除输入。

import React, { useImperativeHandle, forwardRef, useRef } from "react";type TextInputHandles = {clear: () => void;
};const TextInput = forwardRef<TextInputHandles, {}>((props, ref) => {const inputRef = useRef<HTMLInputElement>(null);useImperativeHandle(ref, () => ({clear: () => {if (inputRef.current) {inputRef.current.value = "";}},}));return <input type="text" ref={inputRef} />;
});const ParentComponent = () => {const inputRef = useRef<TextInputHandles>(null);const clearInput = () => {if (inputRef.current) {inputRef.current.clear();}};return (<div><TextInput ref={inputRef} /><button onClick={clearInput}>Clear Input</button></div>);
};export default ParentComponent;

注意事项

  • 谨慎使用: 尽量不要过度使用 useImperativeHandle,因为它可能导致代码更难理解和维护。
  • forwardRef 配合使用: 通常,你需要将子组件与 forwardRef 一起使用,以将 ref 传递给子组件。

总结

虽然 useImperativeHandle 不是常用的钩子,但在需要在父组件中直接操作子组件的特定场景下,它可能是必要的。通过允许你精确地控制父组件可以访问的子组件方法,它提供了一种强大但易于滥用的工具。在使用它时要小心,并确保这确实是解决问题的最佳方式。

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

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

相关文章

若依vue -【 100 ~ 更 】

100 主子表代码生成详解 1 新建数据库表结构&#xff08;主子表&#xff09; -- ---------------------------- -- 客户表 -- ---------------------------- drop table if exists sys_customer; create table sys_customer (customer_id bigint(20) not null…

浅谈AI浪潮下的视频大数据发展趋势与应用

视频大数据的发展趋势是多样化和个性化的。随着科技的不断进步&#xff0c;人们对于视频内容的需求也在不断变化。从传统的电视节目到现在的短视频、直播、VR等多种形式&#xff0c;视频内容已经不再是单一的娱乐方式&#xff0c;更是涉及到教育、医疗、商业等各个领域。 为了满…

【LeetCode】1749.任意子数组和的绝对值的最大值

题目 给你一个整数数组 nums 。一个子数组 [numsl, numsl1, ..., numsr-1, numsr] 的 和的绝对值 为 abs(numsl numsl1 ... numsr-1 numsr) 。 请你找出 nums 中 和的绝对值 最大的任意子数组&#xff08;可能为空&#xff09;&#xff0c;并返回该 最大值 。 abs(x) 定…

MySQL中bigint(20)中的20代表含义

这个20可以理解为数据宽度&#xff0c;不是取值范围。 整数类型 对于整数类型(int&#xff0c;bigint)&#xff0c;取值范围是固定的&#xff0c;例如&#xff1a;int的取值范围是&#xff1a;-2147483648 - 2147483647&#xff0c;就只能存这个范围的数&#xff0c;无论写in…

crypto-js中AES的加解密封装

在项目中安装依赖&#xff1a; npm i crypto-js在使用的页面引入&#xff1a; import CryptoJS from crypto-jscrypto-js中AES的加解密简单的封装了一下&#xff1a; //加密const KEY 000102030405060708090a0b0c0d0e0f // 秘钥 这两个需要和后端统一const IV 8a8c8fd8fe3…

API HOOK技术在MFC程序破解过程中的应用

更新&#xff0c;修改了一下typora的上传脚本&#xff0c;把图片全部上传到看雪上了 本文已于2023-08-02首发于个人博客 图片加载不出来&#xff0c;放了一个PDF版本在附件里 文中有几张图片是动图&#xff0c;如果不会动&#xff0c;可以去我的个人博客看 最近破解了一个M…

图论相关总结

参考&#xff1a;1.https://labuladong.gitee.io/algo/di-yi-zhan-da78c/shou-ba-sh-03a72/tu-lun-ji--d55b2/ 2.代码随想录图论 (qq.com) 例题1&#xff1a;所有可能路径&#xff08;考察图的遍历&#xff09; 给你一个有 n 个节点的 有向无环图&#xff08;DAG&#xff09;…

你不知道的阴影

我们在开发的时候&#xff0c;使用box-shadow添加阴影是这样的&#xff1a; .img {width: 500px;height: 500px;display: block;box-shadow: 0 0 15px #333333;} 但是我们想给这个图片加阴影应该怎么加那&#xff08;让UI做&#xff0c;我真聪明&#xff01;&#xff09; &…

Java基础练习七(二维数组)

1. 翻转数组 设存在以下数组&#xff0c;请正常方法输出: char[][] chunxiao {{ 春 , 眠 , 不 , 觉 , 晓 } ,{ 处 , 处 , 闻 , 啼 , 鸟 } ,{ 夜 , 来 , 风 , 雨 , 声 } ,{ 花 , 落 , 知 , 多 , 少 } };public class Work0901 {public static void main(String[] args) {char[]…

Kali Hyper-V安装正常启动后 黑屏 只能进命令模式

问题: Hyper-V安装虚拟机Kali系统一切安装正常, 没有出现错误. 安装成功后重启,只能进入命令模式,tt1-tt6,进不去GUI桌面. 尝试: 一代二代虚拟硬盘都试过,同样问题,只能开进后进入命令模式,在命令模式下一切运行正常, 也修复过系统 GNOM等的,不管用. 以下为国外论坛给的建议,尝…

Centos7单机部署ElasticSearch

Centos7单机部署ElasticSearch 引言 Elasticsearch是一种广泛使用的开源搜索引擎&#xff0c;专门为分布式环境设计&#xff0c;但也可以在单机上运行。它使存储、搜索和分析大量数据变得更加容易和高效。此教程将引导你通过在Centos7上单机部署Elasticsearch&#xff0c;涵盖…

flutter项目给安卓打正式包 和升级版本号

1.首先把flutter项目里的android目录整个拖进android studo里,运行一下看看是否能运行 2.Build->Generate Signed Bundle/APK… 点击APK->Next 如果没有key酒店及Create new…就生成新的key 点击Key store path:右边的图标选择保存路径 选择保存的路径,并且在Save…

webpack基础知识二:说说webpack的构建流程?

一、运行流程 webpack 的运行流程是一个串行的过程&#xff0c;它的工作流程就是将各个插件串联起来 在运行过程中会广播事件&#xff0c;插件只需要监听它所关心的事件&#xff0c;就能加入到这条webpack机制中&#xff0c;去改变webpack的运作&#xff0c;使得整个系统扩展…

【Android NDK开发】Android Studio 编写 JNI (C++)代码无提示

随笔记 Android Studio在编写C代码时候&#xff0c;引入对应的头文件&#xff0c;Android Studio里却不提示对应的方法&#xff0c;需要在Studio中设置一下。 Mac中&#xff0c;选择 Android Studio > Preferences&#xff0c;选择Clangd >>Disable Clangd completio…

C++-排序

文章目录 常数操作时间复杂度空间复杂度O(N^2) O(1) 数据情况发生变化不影响流程 选择排序冒泡排序使用抑或运算提取出不为零的数最右边的1 1. 实现两个变量交换值2. 数组中一种数字出现奇数次,other是偶数次,找到那一种数字3. 数组中有两种数字出现奇数次,other是偶数次,找到那…

【LeetCode】1281.整数的各位积和之差

题目 给你一个整数 n&#xff0c;请你帮忙计算并返回该整数「各位数字之积」与「各位数字之和」的差。 示例 1&#xff1a; 输入&#xff1a;n 234 输出&#xff1a;15 解释&#xff1a; 各位数之积 2 * 3 * 4 24 各位数之和 2 3 4 9 结果 24 - 9 15示例 2&…

如何理解MySQL隔离性---3个记录隐藏字段、undo日志、Read View

目录 一、3个记录隐藏字段 二、undo 日志 三、read view 一、3个记录隐藏字段 本片文章是帮助理解上篇文章Mysql隔离性的辅助知识。 mysql在建表时&#xff0c;不仅仅创建了表的结构&#xff0c;还创建了3个隐藏字段。 DB_TRX_ID &#xff1a;6 byte&#xff0c;最近修改( 修…

微信抢红包操作步骤及需要安装软件的步骤

微信抢红包操作步骤&#xff1a; 打开微信&#xff0c;进入聊天窗口。 在聊天窗口中&#xff0c;如果有红包消息会显示“红包”字样&#xff0c;点击这条消息。 在红包界面&#xff0c;点击“抢红包”按钮。 如果是口令红包&#xff0c;需要输入正确的口令才能打开红包。 打开红…

iOS开发-JsonModel的学习及使用

IOS JsonModel的学习及使用 当我们从服务端获取到json数据后的时候&#xff0c;我们需要在界面上展示或者保存起来&#xff0c;下面来看下直接通过NSDictionary取出数据的情况。 NSDictionary直接取出数据的诟病。 NSString *name [self.responseObj objectForKey:"nam…

巧用Maya轴心操作技巧,让工作事半功倍!

Maya 是一款专业的三维软件&#xff0c;可以用于创建规模宏大的世界、复杂的角色和炫酷的特效。Maya的用户遍布动画行业、影视特效、广告和片头、平面设计行业&#xff0c;用户数量十分庞大。本文分享了maya轴心操作的小技巧&#xff0c;让设计师工作事半功倍&#xff0c;一起来…