当前位置: 首页 > news >正文

【React】React学习:从初级到高级(四)

React学习[四]

  • 4 应急方案
    • 4.1 使用ref引用值
      • 4.1.1 给组件添加`ref`
      • 4.1.2 ref和state的不同之处
      • 4.1.3 何时使用ref
    • 4.2 使用ref操作DOM
      • 4.2.1 获取指向节点的ref
      • 4.2.3 使用 ref 回调管理 ref 列表
      • 4.2.4 访问另一个组件的DOM节点
      • 4.2.5 用 flushSync 同步更新 state
    • 4.3 使用Effect同步
    • 4.4 不需要Effect的情况
    • 4.5 响应式Effect的生命周期
      • 4.5.1 effect的生命周期
      • 4.5.2 Effect只应该依赖变量
    • 4.6 将事件从Effect中分开
      • 4.6.1 在事件处理函数和Effect中做选择
      • 4.6.2 从Effect中提取非响应式逻辑
      • 4.6.3 使用Effect Event 读取最新的props和state
    • 4.7 移除Effect依赖
      • 4.7.1 依赖应该和代码保持一致
      • 4.7.2 移除非必须的依赖
    • 4.8 使用自定义Hook复用逻辑
      • 4.8.1 从组件中提取自定义Hook
      • 4.8.2 把事件处理函数传到自定义Hook中
      • 4.8.3 什么时候使用自定义Hook

4 应急方案

4.1 使用ref引用值

当希望组件“记住”某些信息,但又不想让这些信息触发新的渲染时,可以使用 ref

4.1.1 给组件添加ref

导入useRef()

import { useRef } from 'react';

调用useRef

const ref = useRef(0);

可以用 ref.current 属性访问该 ref 的当前值,例如:

ref.current = ref.current + 1;

设置 state 会重新渲染组件,更改 ref 不会!当一条信息用于渲染时,将它保存在 state 中。当一条信息仅被事件处理器需要,并且更改它不需要重新渲染时,使用 ref 可能会更高效。

4.1.2 ref和state的不同之处

refstate
useRef(initialValue)返回 { current: initialValue }useRef(initialValue)返回 { current: initialValue }
更改时不会触发重新渲染更改时触发重新渲染。
可变 —— 可以在渲染过程之外修改和更新 current 的值“不可变” —— 必须使用 state 设置函数来修改 state 变量,从而排队重新渲染。
不应在渲染期间读取(或写入) current 值。可以随时读取 state。但是,每次渲染都有自己不变的 state 快照。

4.1.3 何时使用ref

  1. 存储timeout Id
  2. 存储和操作DOM元素
  3. 存储不需要被用来计算JSX的其他对象

4.2 使用ref操作DOM

有时可能需要访问由 React 管理的 DOM 元素 —— 例如,让一个组件获得焦点、滚动到它或测量它的尺寸和位置。在 React 中没有内置的方法来做这些事情,所以需要一个指向 DOM 节点的 ref 来实现。

4.2.1 获取指向节点的ref

// 第一步,引入Ref
import { useRef } from 'react';
// 第二步,声明一个ref
const myRef = useRef(null);
// 第三步,将ref传入html标签内,比如
<div ref={myRef}>

4.2.3 使用 ref 回调管理 ref 列表

如果需要为列表中的每一项都绑定 ref ,而又不知道会有多少项。那么可以将函数传递给ref属性,称为ref回调。

import { useRef } from 'react';export default function CatFriends() {const itemsRef = useRef(null);function scrollToId(itemId) {const map = getMap();const node = map.get(itemId);node.scrollIntoView({behavior: 'smooth',block: 'nearest',inline: 'center'});}function getMap() {if (!itemsRef.current) {// 首次运行时初始化 Map。itemsRef.current = new Map();}return itemsRef.current;}return (<><nav><button onClick={() => scrollToId(0)}>Tom</button><button onClick={() => scrollToId(5)}>Maru</button><button onClick={() => scrollToId(9)}>Jellylorum</button></nav><div><ul>{catList.map(cat => (<likey={cat.id}ref={(node) => {const map = getMap();if (node) {// 添加到 Mapmap.set(cat.id, node);} else {// 从 Map 删除map.delete(cat.id);}}}><imgsrc={cat.imageUrl}alt={'Cat #' + cat.id}/></li>))}</ul></div></>);
}const catList = [];
for (let i = 0; i < 10; i++) {catList.push({id: i,imageUrl: 'https://placekitten.com/250/200?image=' + i});
}

4.2.4 访问另一个组件的DOM节点

const MyInput = forwardRef((props, ref) => {return <input {...props} ref={ref} />;
});
  1. <MyInput ref={inputRef} /> 告诉 React 将对应的 DOM 节点放入 inputRef.current 中。但是,这取决于 MyInput 组件是否允许这种行为, 默认情况下是不允许的。
  2. MyInput 组件是使用 forwardRef 声明的。 这让从上面接收的 inputRef 作为第二个参数 ref 传入组件,第一个参数是 props
  3. MyInput 组件将自己接收到的 ref 传递给它内部的 <input>

限制暴露的功能:useImperativeHandle

const MyInput = forwardRef((props, ref) => {const realInputRef = useRef(null);useImperativeHandle(ref, () => ({// 只暴露 focus,没有别的focus() {realInputRef.current.focus();},}));return <input {...props} ref={realInputRef} />;
});

4.2.5 用 flushSync 同步更新 state

如果需要强制 React 同步更新(“刷新”)DOM。从 react-dom 导入 flushSync将 state 更新包裹flushSync 调用中:

import { flushSync }  from 'react-dom';
function handleAdd() {const newTodo = { id: nextId++, text: text };flushSync(() => {setText('');setTodos([ ...todos, newTodo]);      });listRef.current.lastChild.scrollIntoView({behavior: 'smooth',block: 'nearest'});}

Refs 是一个应急方案。应该只在必须“跳出 React”时使用它们。这方面的常见示例包括管理焦点、滚动位置或调用 React 未暴露的浏览器 API。


4.3 使用Effect同步

Effects 会在渲染后运行一些代码,以便可以将组件与 React 之外的某些系统同步。不要随意在你的组件中使用 Effect

三个步骤:

  1. 声明Effect

    import { useEffect } from 'react';function MyComponent() {useEffect(() => {// 每次渲染后都会执行此处的代码});return <div />;
    }
  2. 指定Effect依赖。大多数 Effect 应该按需执行,而不是在每次渲染后都执行。

      useEffect(() => {if (isPlaying) { // isPlaying 在此处使用……// ...} else {// ...}}, [isPlaying]); // ……所以它必须在此处声明!
    
  3. 必要时添加清理(cleanUp)函数。有时 Effect 需要指定如何停止、撤销,或者清除它的效果。

    空的依赖数组([])对应于组件“挂载”,即添加到屏幕上。

      useEffect(() => {const connection = createConnection();	// 开启连接connection.connect();return () => {connection.disconnect();   // 断开连接};}, []);
    

控制非React组件

useEffect(() => {const dialog = dialogRef.current;dialog.showModal();return () => dialog.close();
}, []);

订阅事件

如果 Effect 订阅了某些事件,清理函数应该退订这些事件:

useEffect(() => {function handleScroll(e) {console.log(window.scrollX, window.scrollY);}window.addEventListener('scroll', handleScroll);return () => window.removeEventListener('scroll', handleScroll);
}, []);

触发动画

如果 Effect 对某些内容加入了动画,清理函数应将动画重置

useEffect(() => {const node = ref.current;node.style.opacity = 1; // 触发动画return () => {node.style.opacity = 0; // 重置为初始值};
}, []);

获取数据

如果 Effect 将会获取数据,清理函数应该要么 中止该数据获取操作,要么忽略其结果

useEffect(() => {let ignore = false;async function startFetching() {const json = await fetchTodos(userId);if (!ignore) {setTodos(json);}}startFetching();return () => {ignore = true;};
}, [userId]);

为了防止条件竞争,每个 Effect 都可以在里面设置一个 ignore 标记变量。在最开始,ignore 被设置为 false。然而,当 Effect 执行清理函数后(就像你选中了列表中不同的人时),ignore 就会被设置为 true

  • 仅在严格模式下的开发环境中,React 会挂载两次组件,以对 Effect 进行压力测试。
  • React 将在下次 Effect 运行之前以及卸载期间这两个时候调用清理函数。

4.4 不需要Effect的情况

  1. 根据propsstate来更新state

  2. 使用useMemo缓存耗时的计算

    比如:

    import { useMemo, useState } from 'react';function TodoList({ todos, filter }) {const [newTodo, setNewTodo] = useState('');// ✅ 除非 todos 或 filter 发生变化,否则不会重新执行 getFilteredTodos()const visibleTodos = useMemo(() => getFilteredTodos(todos, filter), [todos, filter]);// ...
    }
    

    会告诉 React,除非 todosfilter 发生变化,否则不要重新执行传入的函数

  3. props 变化时重置所有 state 。可以使用key属性来标识。

  4. 当prop变化时调整部分state

    // 虽然下面这种方式比 Effect 更高效,但大多数组件也不需要它
    function List({ items }) {const [isReverse, setIsReverse] = useState(false);const [selection, setSelection] = useState(null);// 好一些:在渲染期间调整 stateconst [prevItems, setPrevItems] = useState(items);if (items !== prevItems) {setPrevItems(items);setSelection(null);}// ...
    }/* -----------优化:在渲染期间计算内容---------- */function List({ items }) {const [isReverse, setIsReverse] = useState(false);const [selectedId, setSelectedId] = useState(null);// ✅ 非常好:在渲染期间计算所需内容const selection = items.find(item => item.id === selectedId) ?? null;// ...
    }

    检查是否可以通过添加 key 来重置所有 state,或者 在渲染期间计算所需内容。

  5. 在事件处理函数中共享逻辑

    如果有组件用到了共同的函数调用,尝试把这个函数抽离出来成为一个独立函数

    function ProductPage({ product, addToCart }) {// ✅ 非常好:事件特定的逻辑在事件处理函数中处理function buyProduct() {addToCart(product);showNotification(`已添加 ${product.name} 进购物车!`);}function handleBuyClick() {buyProduct();}function handleCheckoutClick() {buyProduct();navigateTo('/checkout');}// ...
    }
    
  6. 发送Post请求

    当用户按下按钮发送post请求,只在特定交互中发生

  7. 链式计算

  8. 初始化应用

    每次应用加载时执行一次。可以添加一个顶层变量来记录它是否已经被执行过了。

    let didInit = false;function App() {useEffect(() => {if (!didInit) {didInit = true;// ✅ 只在每次应用加载时执行一次loadDataFromLocalStorage();checkAuthToken();}}, []);// ...
    }
    

    或者在模块初始化和应用渲染之前执行:

    if (typeof window !== 'undefined') { // 检测我们是否在浏览器环境// ✅ 只在每次应用加载时执行一次checkAuthToken();loadDataFromLocalStorage();
    }function App() {// ...
    }
    

    为了避免在导入任意组件时降低性能或产生意外行为,请不要过度使用这种方法。将应用级别的初始化逻辑保留在像 App.js 这样的根组件模块或你的应用入口中。

  9. 通知父组件有关state变化的信息

    可以试试状态提升,由父组件控制state

  10. 将数据传递给父组件

可以让父组件获取数据,并传递给子组件

  1. 订阅外部store

    利用react的Hook函数useSyncExternalStore

    function subscribe(callback) {window.addEventListener('online', callback);window.addEventListener('offline', callback);return () => {window.removeEventListener('online', callback);window.removeEventListener('offline', callback);};
    }function useOnlineStatus() {// ✅ 非常好:用内置的 Hook 订阅外部 storereturn useSyncExternalStore(subscribe, // 只要传递的是同一个函数,React 不会重新订阅() => navigator.onLine, // 如何在客户端获取值() => true // 如何在服务端获取值);
    }function ChatIndicator() {const isOnline = useOnlineStatus();// ...
    }
    
  2. 获取数据

    为了避免条件竞争情况的出现,需要在effect中添加清理函数来忽略较早的返回结果.

    function SearchResults({ query }) {const [results, setResults] = useState([]);const [page, setPage] = useState(1);useEffect(() => {let ignore = false;fetchResults(query, page).then(json => {if (!ignore) {setResults(json);}});return () => {ignore = true;};}, [query, page]);function handleNextPageClick() {setPage(page + 1);}// ...
    }
    

    比使用effect更好的办法是使用框架的内置数据获取机制


4.5 响应式Effect的生命周期

4.5.1 effect的生命周期

每个react组件都经历相同的生命周期

  1. 组件挂载
  2. 组件更新
  3. 组件卸载

但是effect不一样,Effect 能够在需要时始终具备启动和停止的弹性

React会通过在开发环境中立即强制 Effect 重新进行同步来验证其是否能够重新同步。而之所以知道需要重新同步,是因为effect的依赖项发生了变化。

**代码中的每个 Effect 应该代表一个独立的同步过程。**也就是说删除一个 Effect 不会影响另一个 Effect 的逻辑。

4.5.2 Effect只应该依赖变量

Effect的依赖项是变量,变量发生改变后,effect会重新响应。

如果effect没有依赖项,就表明这个effect仅在组件挂载时执行一次,并在组件卸载时清理。

组件内部的所有值(包括 props、state 和组件体内的变量)都是响应式的。任何响应式值都可以在重新渲染时发生变化,所以需要将响应式值包括在 Effect 的依赖项中

全局变量或可变值不可以作为依赖。应该使用 useSyncExternalStore 来读取和订阅外部可变值。

如果出现无限循环的问题,或者 Effect 过于频繁地重新进行同步,可以尝试以下解决方案:

  • 检查Effect是否表示了独立的同步过程。
  • 如果想读取 props 或 state 的最新值,但又不想对其做出反应并重新同步 Effect,可以将 Effect 拆分为具有反应性的部分(保留在 Effect 中)和非反应性的部分(提取为名为 “Effect Event” 的内容)
  • 避免将对象和函数作为依赖项

挑战:一个下拉框允许用户选择一个行星,而另一个下拉框应该显示该选定行星上的地点。然而,目前这两个下拉框都还没有正常工作。你的任务是添加一些额外的代码,使得选择一个行星时,placeList 状态变量被填充为 "/planets/" + planetId + "/places" API 调用的结果。

App.js

import { useState, useEffect } from 'react';
import { fetchData } from './api.js';export default function Page() {const [planetList, setPlanetList] = useState([])const [planetId, setPlanetId] = useState('');const [placeList, setPlaceList] = useState([]);const [placeId, setPlaceId] = useState('');useEffect(() => {let ignore = false;fetchData('/planets').then(result => {if (!ignore) {console.log('获取了一个行星列表。');setPlanetList(result);setPlanetId(result[0].id); // 选择第一个行星}});return () => {ignore = true;}}, []);useEffect(() => {if (planetId === '') {return;}let ignore = false;fetchData('/planets/' + planetId + '/places').then(result => {if (!ignore) {console.log('获取了该行星的地点列表');setPlaceList(result);setPlaceId(result[0].id);}});return () => {ignore = true;}}, [planetId])return (<><label>选择一个行星:{' '}<select value={planetId} onChange={e => {setPlanetId(e.target.value);}}>{planetList?.map(planet =><option key={planet.id} value={planet.id}>{planet.name}</option>)}</select></label><label>选择一个地点:{' '}<select value={placeId} onChange={e => {setPlaceId(e.target.value);}}>{placeList?.map(place =><option key={place.id} value={place.id}>{place.name}</option>)}</select></label><hr /><p>你将要前往:{planetId || '...'}{placeId || '...'} </p></>);
}

理想情况下,应用程序中的大多数 Effect 最终都应该由自定义 Hook 替代,无论是由你自己编写还是由社区提供。为了减少一些重复,可以把一些逻辑提取到自定义Hook中。

App.js

import { useState } from 'react';
import { useSelectOptions } from './useSelectOptions.js';export default function Page() {const [planetList,planetId,setPlanetId] = useSelectOptions('/planets');const [placeList,placeId,setPlaceId] = useSelectOptions(planetId ? `/planets/${planetId}/places` : null);return (<><label>选择一个行星:{' '}<select value={planetId} onChange={e => {setPlanetId(e.target.value);}}>{planetList?.map(planet =><option key={planet.id} value={planet.id}>{planet.name}</option>)}</select></label><label>选择一个地点:{' '}<select value={placeId} onChange={e => {setPlaceId(e.target.value);}}>{placeList?.map(place =><option key={place.id} value={place.id}>{place.name}</option>)}</select></label><hr /><p>你将要前往:{planetId || '...'}{placeId || '...'} </p></>);
}

useSelectOptions.js

import { useState, useEffect } from 'react';
import { fetchData } from './api.js';export function useSelectOptions(url) {const [list, setList] = useState(null);const [selectedId, setSelectedId] = useState('');useEffect(() => {if (url === null) {return;}let ignore = false;fetchData(url).then(result => {if (!ignore) {setList(result);setSelectedId(result[0].id);}});return () => {ignore = true;}}, [url]);return [list, selectedId, setSelectedId];
}

4.6 将事件从Effect中分开

4.6.1 在事件处理函数和Effect中做选择

事件处理函数:

  1. 只在响应特定的交互操作时运行
  2. 事件处理函数内部的逻辑是非响应式的

Effect:

  1. 需要同步时,比如保持服务器连接
  2. Effect内部的逻辑是响应式的

组件内部声明的 state 和 props 变量被称为响应式值。这些响应式值参与组件的渲染数据流。

4.6.2 从Effect中提取非响应式逻辑

声明一个Effect Event:尚未发布到React正式版中(截至2023.8.15)。

import { useEffect, useEffectEvent } from 'react';function ChatRoom({ roomId, theme }) {const onConnected = useEffectEvent(() => {showNotification('Connected!', theme);});

之后可以在Effect内部调用onConnected:

function ChatRoom({ roomId, theme }) {const onConnected = useEffectEvent(() => {showNotification('Connected!', theme);});useEffect(() => {const connection = createConnection(serverUrl, roomId);connection.on('connected', () => {onConnected();});connection.connect();return () => connection.disconnect();}, [roomId]); // ✅ 声明所有依赖项

4.6.3 使用Effect Event 读取最新的props和state

尚未发布到React正式版中(截至2023.8.15)。

function Page({ url }) {const { items } = useContext(ShoppingCartContext);const numberOfItems = items.length;const onVisit = useEffectEvent(visitedUrl => {logVisit(visitedUrl, numberOfItems);});useEffect(() => {onVisit(url);}, [url]); // ✅ 声明所有依赖项// ...
}

这里的 onVisit 是一个 Effect Event。里面的代码不是响应式的。另一方面,Effect 本身仍然是响应式的。其内部的代码使用了 url props,所以每次因为不同的 url 重新渲染后 Effect 都会重新运行。这会依次调用 onVisit 这个 Effect Event。

Effect Event 的局限性在于你如何使用他们:

  • 只在 Effect 内部调用他们
  • 永远不要把他们传给其他的组件或者 Hook

4.7 移除Effect依赖

4.7.1 依赖应该和代码保持一致

  • 编写 Effect 时,无论这个 Effect 要做什么,首先要明确其生命周期,什么时候同步,什么时候需要清理。
  • 确保Effect的依赖项与函数代码里的变量一致。每个被Effect使用的响应值必须在依赖中声明。
  • 要移除一个依赖,需要向linter证明其不需要这个依赖。
  • 要改变依赖,也要考虑代码需不需要改变。

**建议将依赖性 lint 错误作为一个编译错误来处理。**不然有可能会遇到你并不知道是什么的bug。

4.7.2 移除非必须的依赖

需要考虑的问题:

  1. 这段代码应该移到事件处理程序中吗?

    避免Effect 中有特定的事件处理逻辑代码。

  2. Effect是否在做几件不相关的事情?

    每个effect应该代表一个独立的同步过程。如果担心代码重复,可以提取相同逻辑到自定义Hook来提升代码质量。

  3. 是否在读取一些状态来计算下一个状态?

  4. 将非响应式逻辑移至Effect Event中(正式版未发布)

  5. Effect Event 包装来自props的事件处理程序

  6. 尽可能避免将对象和函数作为 Effect 的依赖

  7. 将静态对象和函数移除组件

  8. 将动态对象和函数移动到effect中

  9. 从对象中读取原始值

    从 Effect 外部 读取对象信息,并避免依赖对象和函数类型:

    function ChatRoom({ options }) {const [message, setMessage] = useState('');const { roomId, serverUrl } = options;useEffect(() => {const connection = createConnection({roomId: roomId,serverUrl: serverUrl});connection.connect();return () => connection.disconnect();}, [roomId, serverUrl]); // ✅ 所有依赖已声明// ...
    
  10. 从函数中计算原始值

​ 假设父组件传了一个函数:

<ChatRoomroomId={roomId}getOptions={() => {return {serverUrl: serverUrl,roomId: roomId};}}
/>

为避免使其成为依赖(并导致它在重新渲染时重新连接),需要在 Effect 外部调用它:

function ChatRoom({ getOptions }) {const [message, setMessage] = useState('');const { roomId, serverUrl } = getOptions();useEffect(() => {const connection = createConnection({roomId: roomId,serverUrl: serverUrl});connection.connect();return () => connection.disconnect();}, [roomId, serverUrl]); // ✅ 所有依赖已声明// ...

这仅适用于 纯函数,因为它们在渲染期间可以安全调用。如果函数是一个事件处理程序,但你不希望它的更改重新同步 Effect,将它包装到 Effect Event 中。

4.8 使用自定义Hook复用逻辑

4.8.1 从组件中提取自定义Hook

如果一个Effect中的逻辑有多个组件用到了,就可以考虑将重复逻辑部分提取出来。

Hook的名称必须以’use’开头

自定义Hook共享的是状态逻辑,而不是状态本身对同一个 Hook 的每个调用是各自完全独立的

4.8.2 把事件处理函数传到自定义Hook中

使用了useEffect

import { useEffect, useEffectEvent } from 'react';
// ...export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) {const onMessage = useEffectEvent(onReceiveMessage);useEffect(() => {const options = {serverUrl: serverUrl,roomId: roomId};const connection = createConnection(options);connection.connect();connection.on('message', (msg) => {onMessage(msg);});return () => connection.disconnect();}, [roomId, serverUrl]); // ✅ 声明所有依赖
}

4.8.3 什么时候使用自定义Hook

首先明白一件事,就是如果你需要写Effect就意味着需要"走出React"和某些外部系统同步,或者需要做一些react中没有对应内置API的事。

使用自定义Hook时需要专注于高级用例,避免使用react生命周期,比如useMount,每个自定义Hook应该专注于实现一个功能。

把Effect包裹进自定义Hook有益的另一些原因:

  • 让进出 Effect 的数据流非常清晰。
  • 让组件专注于目标,而不是 Effect 的准确实现。
  • 当 React 增加新特性时,可以在不修改任何组件的情况下移除这些 Effect。

相关文章:

【React】React学习:从初级到高级(四)

React学习[四] 4 应急方案4.1 使用ref引用值4.1.1 给组件添加ref4.1.2 ref和state的不同之处4.1.3 何时使用ref 4.2 使用ref操作DOM4.2.1 获取指向节点的ref4.2.3 使用 ref 回调管理 ref 列表4.2.4 访问另一个组件的DOM节点4.2.5 用 flushSync 同步更新 state 4.3 使用Effect同…...

微信小程序登录问题(思路简略笔记)

配置问题 这是小程序登录问题&#xff0c;必要的两个配置。 流程思路 1. 微信小程序端&#xff0c;会返回一个code。 2. 查看需要返回给微信小程序端的数据。 3. 既然需要返回三个数据&#xff0c;先看openid如何拿到 WX-Login https://api.weixin.qq.com/sns/jscode2ses…...

Go 锁扩展

文章目录 TryLock统计 goroutine数量读写锁读锁写锁常见死锁情况写锁重入写锁中调用读锁循环依赖 TryLock 源码中自带的(我的go是 1.20版本)TryLock 会尝试获取锁&#xff0c;如果获取不到返回false&#xff0c;并不会进行休眠阻塞(和 Lock的主要区别) func (m *Mutex) TryLo…...

Docker的简介及安装

[shouce]http://shouce.jb51.net/docker_practice/栾一峰菜鸟教程参考文献 1 环境配置的难题 软件开发最大的麻烦事之一&#xff0c;就是环境配置。用户计算机的环境都不相同&#xff0c;你怎么知道自家的软件&#xff0c;能在那些机器跑起来&#xff1f; 用户必须保证两件事…...

安卓核心板的不同核心规格及架构介绍

安卓核心板是将核心功能封装的一块电子主板&#xff0c;集成芯片、存储器和功放器件等&#xff0c;并提供标准接口的芯片。 其特点&#xff1a; ● 能跑 Android 等操作系统 强大的功能及丰富的接口 支持 LCD/TP&#xff0c;Audio&#xff0c;Camera&#xff0c;Video&#…...

flume1.11.0安装部署

1、准备安装包apache-flume-1.11.0-bin.tar.gz&#xff1b; 上传&#xff1b; 2、安装flume-1.11.0&#xff1b; 解压&#xff1b; tar -zxvf apache-flume-1.11.0-bin.tar.gz -C /opt/server 进入conf目录&#xff0c;修改flume-env.sh&#xff0c;配置JAVA_HOME&#xff1b…...

通过wordpress 自定义主题的额外CSS删除指定区块

最近用wordpress建站&#xff0c;想要删除指定区块&#xff0c;发现相关的教程蛮少的&#xff0c;作为小白的我搜了相关教程&#xff0c;好像没找到&#xff0c;只能自己慢慢摸索了&#xff0c;看了很多&#xff0c;终于尝试实现了&#xff0c;特记录下&#xff0c;免得自己忘了…...

Rokid Jungle--Max pro

介绍和功能开发 YodaOS-Master操作系统&#xff1a;以交换计算为核心&#xff0c;实现单目SLAM空间交互&#xff0c;具有高精度、实时性和稳定性。发布UXR2.0SDK&#xff0c;为构建空间内容提供丰富的开发套件 多模态交互 算法原子化 多种开发工具协同 多生态支持 骁龙XR2…...

【LeetCode算法系列题解】第61~65题

CONTENTS LeetCode 61. 旋转链表&#xff08;中等&#xff09;LeetCode 62. 不同路径&#xff08;中等&#xff09;LeetCode 63. 不同路径 II&#xff08;中等&#xff09;LeetCode 64. 最小路径和&#xff08;中等&#xff09;LeetCode 65. 有效数字&#xff08;困难&#xff…...

MATLAB中fillmissing函数用法

目录 语法 说明 示例 包含 NaN 值的向量 由 NaN 值组成的矩阵 插入缺失数据 使用移动中位数方法 使用自定义填充方法 包含缺失端点的矩阵 包含多个数据类型的表 fillmissing函数的功能是填充缺失的条目。 语法 F fillmissing(A,constant,v) F fillmissing(A,meth…...

电脑同时连接有线和无线网络怎么设置网络的优先级

电脑同时连接有线和无线网络怎么设置网络的优先级&#xff1a; 我们知道在 笔记本电脑系统 中&#xff0c;可以通过有线或无线网络进行联网。如果电脑在有线网络和无线网络同时存在的情况&#xff0c;应该怎么设置有线网络优先连接呢?对此我们提供下面的方法可以让电脑在有Wi…...

el-form表单动态校验(场景: 输入框根据单选项来动态校验表单 没有选中的选项就不用校验)

el-form表单动态校验 el-form常规校验方式: // 结构部分 <el-form ref"form" :model"form" :rules"rules"><el-form-item label"活动名称: " prop"name" required><el-input v-model"form.name" /…...

Java 数据结构与算法应该如何学习?

学习数据结构是计算机科学和软件工程领域中的重要基础知识之一。掌握数据结构对于编写高效、可扩展和可维护的代码至关重要。 1、掌握基本概念 首先&#xff0c;你需要掌握数据结构的基本概念。了解不同类型的数据结构&#xff0c;如数组、链表、栈、队列、树、图等&#xff…...

力扣(LeetCode)算法_C++——有效的数独

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例图&#xff09; …...

制造企业如何优化物料控制?

导 读 ( 文/ 2127 ) 物料控制是指对制造过程中所涉及的物料流动和库存进行有效管理和控制的过程。它包括物料需求计划、供应商管理、物料采购、物料接收和入库、物料库存管理以及物料发放和使用等关键环节。通过精确的物料需求计划和库存管理&#xff0c;物料控制可以确保物料供…...

《Go语言在微服务中的崛起:为什么Go是下一个后端之星?》

&#x1f337;&#x1f341; 博主猫头虎&#x1f405;&#x1f43e; 带您进入 Golang 语言的新世界✨✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文并茂&#x1f…...

因为axios请求后端,接收不到token的问引出的问题

vue axios请求后端接受不到token的问题。 相关概念 什么是跨域&#xff1f; 跨域指的是在浏览器环境下&#xff0c;当发起请求的域&#xff08;或者网站&#xff09;与请求的资源所在的域之间存在协议、主机或端口中的任何一个条件不同的情况。换句话说&#xff0c;只要协议、…...

Stable Diffusion 免费升级 SDXL 1.0,哪些新特性值得关注?体验如何?5 分钟带你体验!

一、引言 7 月 26 日&#xff0c;Stability AI 发布了 SDXL 1.0&#xff0c;号称目前为止&#xff0c;最厉害的开放式图像生成大模型。 它到底有没有网上说的那么炸裂&#xff1f;真的已经实现了像 midjourney 一样 靠嘴出图 的功能吗&#xff1f;相对于之前的版本&#xff0c;…...

【广州华锐互动】煤矿设备AR远程巡检系统实现对井下作业的远程监控和管理

煤矿井下作业环境复杂&#xff0c;安全隐患较多。传统的巡检方式存在诸多弊端&#xff0c;如巡检人员难以全面了解井下情况&#xff0c;巡检效率低下&#xff0c;安全隐患难以及时发现和整改等。为了解决这些问题&#xff0c;提高煤矿安全生产水平&#xff0c;越来越多的企业开…...

C语言与Java语言传输数据 需要转位

在Java语言中&#xff0c;可以通过将整数反转并修改字节顺序来实现低位转高位的转换。下面是一个示例代码&#xff0c;可以将一个整数从低位转高位&#xff1a; public static int toHH(int n) {byte[] bytes ByteBuffer.allocate(4).putInt(n).array();for (int i 0; i <…...

Framework开发——系统默认语言修改

Android 系统原版默认的语言为英文,但是对于中国大陆 Android 产品厂商来说,我们定制系统可能需要用户一开机就是简体中文。所以把 Android 系统出厂设置为简体中文对于 Android 系统产品化非常重要,我们可以通过修改系统属性来达到默认语言的作用。本文主要是在 Android 11…...

浅谈原型链

一.在掌握原型链之前首先要了解这三点 1.每个函数都有prototype这个属性我们称为原型对象 2.每个对象都有__proto__这个属性 3.对象的__proto__可以访问原型对象上的方法和变量,如果访问不了,就会向上进行查找,直到找不到为止,会出现报错的情况l。 二.例子 1.代码: let arr …...

合宙Air724UG LuatOS-Air LVGL API控件-截屏(Screenshots)

截屏&#xff08;Screenshots&#xff09; 分 享导出pdf 截屏功能&#xff0c;core版本号要>3211 示例代码 -- 创建图片控件img lvgl.img_create(lvgl.scr_act(), nil)-- 设置图片显示的图像lvgl.img_set_src(img, "/lua/test.png")-- 图片居中lvgl.obj_align(…...

【系统设计系列】 负载均衡和反向代理

系统设计系列初衷 System Design Primer&#xff1a; 英文文档 GitHub - donnemartin/system-design-primer: Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards. 中文版&#xff1a; https://github.com/donnemart…...

Halcon实现3维点云平面拟合

Halcon实现3维点云平面拟合 function main()WindowHandle open_window()ObjectModel3D load_3D_model("1.om3")ObjectModel3DSelected remove_noise(ObjectModel3D)[X, Y, Z] extract_coordinates(ObjectModel3DSelected)[NX, NY, NZ, C] fit_plane(X, Y, Z)vi…...

安全学习DAY23_CookieSessionToken

文章目录 Cookie和Session的区别Token的作用 Cookie和Session的区别 Cookie和Session都是用来在Web应用程序中跟踪用户状态的机制 1、存储位置不同&#xff1a; Cookie是存储在客户端&#xff08;浏览器&#xff09;上的&#xff0c;而Session是存储在服务器端的。 2、安全…...

C++ map clear内存泄漏问题

map值存的是指针 map自带的clear()函数会清空map里存储的所有内容&#xff0c;但如果map值存储的是指针&#xff0c;则里面的值不会被清空&#xff0c;会造成内存泄漏&#xff0c;所以值为指针的map必须用迭代器清空。 使用erase迭代删除 迭代器删除值为指针的map&#xff0c…...

【鲁棒电力系统状态估计】基于投影统计的电力系统状态估计的鲁棒GM估计器(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

怎么判断一个ip地址是否正确

在网络通信和计算机领域中&#xff0c;IP地址&#xff08;Internet Protocol Address&#xff09;是一个关键的概念。但是&#xff0c;很多人对于如何判断一个IP地址是否正确感到困惑。本文将深入探讨这个问题&#xff0c;并提供一些实用的方法来验证IP地址的正确性。 IP地址是…...

Git:git clone 之 --recursive 选项

在git的repo中&#xff0c;可能会有子项目的代码&#xff0c;也就是"git中的git" --recursive是递归的意思&#xff0c;不仅会git clone当前项目中的代码&#xff0c;也会clone项目中子项目的代码。 我们有时在git clone的时候漏掉 --recursive选项&#xff0c;导致编…...

望野王/搜索引擎优化是免费的吗

http://jquery.andreaseberhard.de/pngFix/ 一、下载所需文件 下载jquery最新版本 http://www.jquery.com 下载pngFix包 http://files.cnblogs.com/ishibin/pngFix.zip 二、在head标签之间加入代码 <head> ... <script type"text/javascript" src"jq…...

我要自学网app/厦门seo外包

我在去年Teched上的课程视频录像&#xff0c;最终获得了整个Teched期间分值排名Top 5的课程。过去了一年时间&#xff0c;当年讲课的录像翻起来看似乎仍不过时。在开始之前再多说两句&#xff1a;从我的角度来看&#xff0c;整个课程是Teched 2012 《60分钟构建私有云 》课程的…...

郑州web网站建设公司/如何推广网站

一、创造价值的公司 选择好公司&#xff0c;才是长期投资的锚&#xff01; 二、价值匹配公司的成长性 这里是赚公司成长的钱&#xff01; 三、价值的精华需要时间去洗涤&#xff01; 这里是赚公司估值修复的钱&#xff01;...

青岛专业网站开发/网站优化方案设计

一、实现功能判断在指定坐标范围内&#xff0c;是否存在相似度大于n的图片&#xff0c;并返回坐标。二、基本思路A你需要寻找的图片B截取当前页面中指定范围的图片利用opencv 判断A在B中的位置&#xff0c;在该位置截取与A图同大小的图片C对比图片C与图片A的相似度三、实现的代…...

网络营销的网站定位/湖南株洲疫情最新情况

原文:清理sql2012数据库日志--1.先把数据库设置为简单模式&#xff08;右击数据库名->点属性->点选项->恢复模式改成简单->点确定按钮,--2.再执行下面的语句(或者右击数据库点任务->收缩->文件&#xff0c;文件件类型选日志&#xff0c;再点确定按钮)use [db…...

织梦做企业网站/百度软件中心官网

Z-TEK USB转串口驱动是一款能够将USB接口转换为串口接口的驱动程序&#xff0c;此驱动主要适合于那些没有串口的计算机设备&#xff0c;有需要的朋友可以来下载试试。【安装方法】驱动安装后&#xff0c;如果您在执行PL-2303 Driver Installer.exe前曾插入传输线&#xff0c;请…...