React高级Hook

useReducer 

useReducer 是 React 提供的一个 Hook,用于在函数组件中使用 reducer 函数来管理组件的 state。它类似于 Redux 中的 reducer,但仅用于组件内部的状态管理。useReducer 可以使复杂的状态逻辑更加清晰和可维护。

基本用法

useReducer 接收一个 reducer 函数和一个初始状态,并返回当前的 state 和一个 dispatch 函数。你可以通过 dispatch 函数来触发 reducer 函数,并传递一个 action 对象,reducer 根据 action 来更新 state。

参数
  1. reducer (Function): 一个纯函数,它接收当前的 state 和一个 action 对象,并返回一个新的 state。
  2. initialState (any): 组件的初始状态。
  3. [init (Function)] (可选): 一个可选的初始化函数,如果提供,它将在 reducer 调用之前被调用,以生成初始 state。它接收 initialState 并返回经过初始化的 state。
返回值
  1. state (any): 当前的状态。
  2. dispatch (Function): 一个 dispatch 函数,它接收一个 action 对象,并调用 reducer 函数来更新 state。

示例

下面是一个简单的计数器组件示例,展示了如何使用 useReducer

seReducer 是 React 提供的一个 Hook,用于在函数组件中使用 reducer 函数来管理组件的 state。它类似于 Redux 中的 reducer,但仅用于组件内部的状态管理。useReducer 可以使复杂的状态逻辑更加清晰和可维护。

基本用法

useReducer 接收一个 reducer 函数和一个初始状态,并返回当前的 state 和一个 dispatch 函数。你可以通过 dispatch 函数来触发 reducer 函数,并传递一个 action 对象,reducer 根据 action 来更新 state。

参数
  1. reducer (Function): 一个纯函数,它接收当前的 state 和一个 action 对象,并返回一个新的 state。
  2. initialState (any): 组件的初始状态。
  3. [init (Function)] (可选): 一个可选的初始化函数,如果提供,它将在 reducer 调用之前被调用,以生成初始 state。它接收 initialState 并返回经过初始化的 state。
返回值
  1. state (any): 当前的状态。
  2. dispatch (Function): 一个 dispatch 函数,它接收一个 action 对象,并调用 reducer 函数来更新 state。

示例

下面是一个简单的计数器组件示例,展示了如何使用 useReducer

import React, { useReducer } from 'react';  
  
// 定义 action 类型  
const increment = () => ({ type: 'INCREMENT' });  
const decrement = () => ({ type: 'DECREMENT' });  
const reset = () => ({ type: 'RESET' });  
  
// 定义 reducer 函数  
const counterReducer = (state, action) => {  
  switch (action.type) {  
    case 'INCREMENT':  
      return { count: state.count + 1 };  
    case 'DECREMENT':  
      return { count: state.count - 1 };  
    case 'RESET':  
      return { count: 0 };  
    default:  
      throw new Error();  
  }  
};  
  
// 初始状态  
const initialState = { count: 0 };  
  
function Counter() {  
  const [state, dispatch] = useReducer(counterReducer, initialState);  
  
  return (  
    <div>  
      <h1>Count: {state.count}</h1>  
      <button onClick={() => dispatch(increment())}>Increment</button>  
      <button onClick={() => dispatch(decrement())}>Decrement</button>  
      <button onClick={() => dispatch(reset())}>Reset</button>  
    </div>  
  );  
}  
  
export default Counter;

详细说明

  1. 定义 action 类型:
    • incrementdecrementreset 是三个返回 action 对象的函数。每个 action 对象都有一个 type 属性,用于在 reducer 中识别 action。
  2. 定义 reducer 函数:
    • counterReducer 是一个纯函数,它接收当前的 state 和一个 action 对象,并返回一个新的 state
    • 根据 action.type,reducer 更新 state
  3. 初始状态:
    • initialState 是组件的初始状态,这里我们设置 count 为 0。
  4. 使用 useReducer:
    • 在 Counter 组件中,使用 useReducer Hook 传入 counterReducer 和 initialState
    • useReducer 返回当前的 state 和 dispatch 函数。
    • 通过 dispatch 函数调用不同的 action 来更新 state。

复杂示例

在实际应用中,useReducer 通常用于管理更复杂的状态。例如,假设我们有一个待办事项列表。

import React, { useReducer } from 'react';  
  
// 定义 action 类型  
const addTodo = (text) => ({ type: 'ADD_TODO', text });  
const toggleTodo = (id) => ({ type: 'TOGGLE_TODO', id });  
  
// 定义 reducer 函数  
const todoReducer = (state, action) => {  
  switch (action.type) {  
    case 'ADD_TODO':  
      return {  
        ...state,  
        todos: [...state.todos, { id: Date.now(), text: action.text, completed: false }],  
      };  
    case 'TOGGLE_TODO':  
      return {  
        ...state,  
        todos: state.todos.map((todo) =>  
          todo.id === action.id ? { ...todo, completed: !todo.completed } : todo  
        ),  
      };  
    default:  
      throw new Error();  
  }  
};  
  
// 初始状态  
const initialState = { todos: [] };  
  
function TodoApp() {  
  const [state, dispatch] = useReducer(todoReducer, initialState);  
  
  const handleAddTodo = (e) => {  
    const text = e.target.value.trim();  
    if (text) {  
      dispatch(addTodo(text));  
      e.target.value = '';  
    }  
  };  
  
  return (  
    <div>  
      <h1>Todo List</h1>  
      <input type="text" onKeyDown={(e) => e.key === 'Enter' ? handleAddTodo(e) : null} />  
      <button onClick={handleAddTodo}>Add Todo</button>  
      <ul>  
        {state.todos.map((todo) => (  
          <li key={todo.id} style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>  
            <span onClick={() => dispatch(toggleTodo(todo.id))}>  
              {todo.text}  
            </span>  
          </li>  
        ))}  
      </ul>  
    </div>  
  );  
}  
  
export default TodoApp;

 useMemo

useMemo是React提供的一个自定义Hook,它允许你在渲染过程中执行一些昂贵的计算,并且仅在依赖项发生变化时重新计算。这有助于优化性能,避免在每次渲染时都重新计算相同的数值或对象。

基本语法
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  • 第一个参数是一个返回需要记忆值的函数。
  • 第二个参数是一个依赖项数组,这个数组中的值会决定何时重新计算记忆值。
使用场景

useMemo适用于以下场景:

  • 当你有一个计算成本高昂的值,并且这个值在组件的某些渲染中可能保持不变时。
  • 当你想要避免在每次渲染时都重新执行昂贵的计算时。
注意事项
  • useMemo主要用于性能优化,不要滥用。
  • 只有当你确定计算是昂贵的且结果可以安全地在渲染之间共享时才应该使用。
  • useMemo不会阻止渲染,它只会优化计算过程。
使用案例

以下是一个使用useMemo的示例,假设我们有一个React组件,用于显示一个列表中所有项目的名称,并且这个列表可能非常大。我们可以使用useMemo来优化过滤操作,避免在每次渲染时都重新执行过滤逻辑。

import React, { useEffect, useState, useMemo } from 'react';  
  
const LargeListComponent = () => {  
  const [list, setList] = useState([]);  
  const [filterText, setFilterText] = useState('');  
  
  // 模拟一个大型列表的加载  
  useEffect(() => {  
    // 这里通常是从API获取数据,但为了简化,我们使用一个静态数组  
    const largeList = Array.from({ length: 10000 }, (_, i) => ({  
      id: i + 1,  
      name: `Item ${i + 1}`,  
    }));  
    setList(largeList);  
  }, []);  
  
  // 使用useMemo来优化过滤操作  
  const filteredList = useMemo(() => {  
    return list.filter(item =>  
      item.name.toLowerCase().includes(filterText.toLowerCase())  
    );  
  }, [list, filterText]);  
  
  return (  
    <div>  
      <input  
        type="text"  
        value={filterText}  
        onChange={(e) => setFilterText(e.target.value)}  
        placeholder="Filter items..."  
      />  
      <ul>  
        {filteredList.map(item => (  
          <li key={item.id}>{item.name}</li>  
        ))}  
      </ul>  
    </div>  
  );  
};  
  
export default LargeListComponent;

在这个例子中,useMemo接收一个过滤函数和一个依赖项数组[list, filterText]。每当listfilterText发生变化时,useMemo会重新执行过滤函数,并返回一个新的过滤后的列表。如果listfilterText都没有变化,那么useMemo会返回上一次计算的结果,从而避免不必要的过滤操作。

这个优化对于大型列表来说是非常有用的,因为它可以减少不必要的计算量,提高组件的渲染性能。

在React和Vue中,useMemo(React)和computed(Vue)都是用于计算派生状态(或称为“计算属性”)的工具,但它们在使用方式和底层实现上有所不同。

React中的useMemo

useMemo是React的一个Hook,它用于在函数组件中优化性能。当你有一个计算成本高昂的值,并且这个值在组件的某些渲染中可能保持不变时,useMemo可以帮助你避免不必要的计算。

useMemo接收一个创建函数和一个依赖项数组。当依赖项数组中的任何一个值发生变化时,创建函数会重新运行,并返回一个新的值。如果依赖项没有变化,那么useMemo会返回上一次计算的值,从而避免不必要的计算。

需要注意的是,useMemo主要用于性能优化,并且只有在你能确定计算是昂贵的且结果可以安全地在渲染之间共享时才应该使用。

Vue中的computed

在Vue中,computed属性用于声明式地计算派生状态。当你有一个基于组件响应式数据计算出来的值,并且你希望这个值在响应式数据变化时自动更新时,computed是非常有用的。

computed属性可以是基于一个或多个响应式依赖的函数,这些依赖可以是组件的data属性、props或其他computed属性。当这些依赖发生变化时,computed属性会自动重新计算,并且Vue会确保它的值是最新的。

useMemo不同,computed在Vue中是声明式的,并且它总是会在依赖变化时重新计算,而不是基于性能优化的考虑。此外,computed属性还可以被用作模板中的绑定,并且它们具有缓存行为,这意味着如果依赖没有变化,那么computed属性的值也不会变化。

总结

  • useMemo(React):一个性能优化工具,用于避免不必要的昂贵计算。它返回一个记忆化的值,这个值在依赖项没有变化时保持不变。
  • computed(Vue):一个声明式的计算属性,用于基于响应式依赖计算派生状态。它总是会在依赖变化时重新计算,并且具有缓存行为。

React.momo

默认渲染:父组件渲染子组件一起渲染

momo:props不变化时,子组件跳过渲染

父组件重新渲染,正常数组会生成新的引用,如果缓存需要用useMemo

在React中,实际上并不存在名为“React.momo”的API或组件。可能您想要了解的是与“React.momo”名称相近或功能相似的React特性,比如React.memo。以下是对React.memo的详细介绍:

一、定义与用途

React.memo是一个高阶组件(Higher Order Component,简称HOC),它用于缓存组件的渲染结果,从而避免在props相同的情况下进行不必要的重新渲染。这有助于提高应用的性能,特别是在处理大型组件树或频繁更新的场景时。

二、使用方式

React.memo接受一个函数组件作为参数,并返回一个新的组件。这个新的组件会检查其props是否发生变化,如果没有变化,则不会重新渲染内部的函数组件。

import { memo } from 'react';  
  
function MyComponent(props) {  
  // 组件代码  
}  
  
export default memo(MyComponent);

三、深度比较与自定义比较函数

默认情况下,React.memo会对props进行浅比较(shallow comparison)。如果props中的对象或数组包含深层数据结构,并且这些深层数据发生了变化,但引用没有变化(即对象或数组的引用地址没有改变),那么React.memo可能不会触发重新渲染。

为了解决这个问题,可以向React.memo传递一个自定义的比较函数作为第二个参数。这个比较函数将用于确定何时应该重新渲染组件。

function arePropsEqual(prevProps, nextProps) {  
  // 自定义比较逻辑  
  // 例如,进行深度比较  
  return prevProps.someValue === nextProps.someValue;  
}  
  
export default memo(MyComponent, arePropsEqual);

四、注意事项

  1. React.memo只能用于函数组件,不能用于类组件。
  2. 当使用React.memo时,应确保传递给组件的props是可比较的(例如,避免使用函数或undefined作为props的值,因为这些值在浅比较中可能无法准确判断)。
  3. 虽然React.memo可以提高性能,但过度使用也可能导致代码复杂性的增加。因此,应根据实际情况谨慎使用。

综上所述,React.memo是React中用于优化函数组件渲染性能的一个有用工具。通过缓存渲染结果和避免不必要的重新渲染,它可以帮助开发者提高应用的响应速度和用户体验。

useCallback

props传函数,保证子组件不重新渲染

useCallback是React提供的一个Hook函数,主要用于优化函数组件的性能,通过缓存回调函数避免不必要的重复创建和重新渲染。以下是对useCallback的详细解析:

一、基本用法

useCallback接受两个参数:一个回调函数和一个依赖数组。当依赖数组中的任何一个值发生变化时,useCallback会返回一个新的回调函数;否则,它会返回之前缓存的回调函数。

  • 回调函数:这是需要被缓存的函数,通常是在组件中需要多次调用的函数。
  • 依赖数组:这是一个包含依赖项的数组。当这些依赖项发生变化时,useCallback会重新创建一个新的回调函数。

二、示例代码

以下是一个简单的示例,展示了如何使用useCallback:

import React, { useCallback, useState } from 'react';  
  
function MyComponent() {  
  const [count, setCount] = useState(0);  
  
  // 使用useCallback缓存回调函数  
  const handleClick = useCallback(() => {  
    console.log(`Clicked ${count} times`);  
  }, [count]);  
  
  return (  
    <>  
      <div>Count: {count}</div>  
      <button onClick={() => setCount(count + 1)}>Increment</button>  
      <button onClick={handleClick}>Click me</button>  
    </>  
  );  
}

在上面的代码中,handleClick回调函数依赖于count状态,因此每次count状态改变时,useCallback都会返回一个新的回调函数。

三、使用场景

useCallback通常用于以下场景:

  1. 将回调函数传递给子组件:当父组件将回调函数传递给子组件时,如果回调函数在每次父组件渲染时都重新创建,那么子组件可能会因为接收到新的函数引用而重新渲染。使用useCallback可以缓存回调函数,避免子组件的不必要重新渲染。
  2. 优化性能:在组件中频繁调用同一个回调函数时,使用useCallback可以避免每次调用都重新创建函数实例,从而提高性能。

四、注意事项

  1. 不要过度使用:虽然useCallback可以提高性能,但过度使用可能会导致代码变得复杂和难以维护。因此,应该根据实际需求合理使用。
  2. 依赖项要准确:在使用useCallback时,要确保依赖项数组中的值是准确的。如果遗漏了某个依赖项,可能会导致回调函数在依赖项变化时没有更新,从而引发bug。
  3. 与memo配合使用:useCallback通常与React.memo一起使用,以实现更高效的组件渲染。React.memo可以对组件的props进行浅层比较,如果props没有变化,则不会重新渲染组件。

五、性能优化讨论

关于useCallback的性能优化效果,存在一些不同的观点。一方面,使用useCallback可以避免不必要的函数重复创建和渲染,从而提高性能;另一方面,React的性能优化机制已经足够智能,可以自动处理很多情况下的函数重复创建。因此,在某些情况下,不使用useCallback也不会对性能产生显著影响。然而,在大型应用中或当回调函数被频繁调用时,使用useCallback仍然是一个值得考虑的优化手段。

综上所述,useCallback是React中一个非常有用的Hook函数,它可以帮助开发者优化函数组件的性能。通过合理使用useCallback和依赖项数组,可以避免不必要的函数重复创建和渲染,从而提高应用的性能和响应速度。

forwardRef

向父组件暴露DOM

React中的forwardRef是一个重要的API,它允许将ref自动地通过组件传递给其子组件。以下是对forwardRef的详细解析:

一、基本概念

forwardRef是React提供的一个高阶组件(HOC)或称为一个函数,用于解决在函数组件中无法直接使用ref的问题。在React中,refs通常用于访问DOM节点或组件实例,但在函数组件中,由于它们没有实例,因此无法直接使用ref。forwardRef允许我们将ref从父组件传递到子组件中的DOM元素或函数式组件。

二、工作原理

forwardRef的工作原理是接受一个渲染函数作为参数,该函数接收props和ref作为参数,并返回React元素。这样,父组件就可以通过ref属性将ref传递给被forwardRef包装的组件,而该组件则可以将这个ref转发给其内部的DOM元素或另一个组件。

三、使用场景

  1. 访问DOM元素:当需要从父组件直接访问子组件的DOM元素时,可以使用forwardRef。例如,当需要直接操作子组件的焦点、触发动画或测量子DOM节点的尺寸时,forwardRef非常有用。
  2. 高阶组件:在高阶组件中,经常需要将被包装的组件的ref传递给内部的某个子组件。这时,forwardRef可以确保ref能够正确地传递。
  3. 组件库开发:在设计可重用的组件库时,通常组件内部的实现细节是不暴露给使用者的。但有时外部需要对这些封装后的子组件进行操作,这时forwardRef可以提供一个简单而有效的解决方案。

四、示例代码

以下是一个使用forwardRef的示例代码:

import React, { forwardRef, useRef } from 'react';  
  
// 定义一个使用forwardRef的组件  
const FancyButton = forwardRef((props, ref) => (  
  <button ref={ref} className="FancyButton">  
    {props.children}  
  </button>  
));  
  
// 在父组件中使用FancyButton并传递ref  
const App = () => {  
  const buttonRef = useRef();  
  
  const handleClick = () => {  
    // 通过ref直接访问DOM元素并触发点击事件  
    buttonRef.current.click();  
  };  
  
  return (  
    <div>  
      <FancyButton ref={buttonRef}>Click me!</FancyButton>  
      <button onClick={handleClick}>Programmatically click FancyButton</button>  
    </div>  
  );  
};  
  
export default App;

在上面的代码中,FancyButton组件使用了forwardRef来接收父组件传递的ref,并将其转发给内部的button元素。在父组件App中,通过useRef创建了一个ref,并将其传递给FancyButton组件。然后,通过ref直接访问了FancyButton组件内部的button元素,并触发了其点击事件。

五、注意事项

  1. 正确使用ref:在使用forwardRef时,需要确保将ref正确地传递给相应的子组件或DOM元素。否则,将无法访问到子组件的实例或DOM元素。
  2. 避免过度使用:虽然forwardRef提供了在函数组件中使用ref的能力,但过度使用可能会导致代码变得复杂和难以维护。因此,应该根据实际需求合理使用。
  3. 与类组件的区别:在类组件中,可以直接使用ref来访问组件实例。但在函数组件中,由于它们没有实例,因此需要使用forwardRef来间接访问DOM元素或子组件。

综上所述,forwardRef是React中一个非常有用的API,它允许在函数组件中通过ref访问子组件的DOM元素或实例。通过合理使用forwardRef,可以实现更精细化的UI控制和组件管理。

useImperativeHandle 

向外暴露方法

useImperativeHandle 是 React 中的一个 Hook,它允许你在使用 ref 时自定义暴露给父组件的实例值。以下是对 useImperativeHandle 的详细解析:

一、作用

useImperativeHandle 的主要作用是让子组件能够选择性地暴露给父组件某些属性或方法,而不是将所有属性和方法都暴露出去。这对于需要在父组件中调用子组件方法或访问子组件状态的场景非常有用。

二、使用场景

当父组件需要使用子组件的方法或属性时,可以通过 ref 和 useImperativeHandle 来实现。例如,父组件可能需要调用子组件的 focus 方法来聚焦输入框,或者访问子组件的某些状态。

三、使用步骤

  1. 父组件中创建 ref

    • 使用 useRef(函数组件)或 createRef(类组件)创建一个 ref 对象。
  2. 子组件中使用 forwardRef

    • 使用 React.forwardRef 包装子组件,以便能够接收和使用 ref。
  3. 子组件中使用 useImperativeHandle

    • 在子组件内部,使用 useImperativeHandle 钩子函数来定义要暴露给父组件的属性或方法。
    • useImperativeHandle 的第一个参数是 ref,第二个参数是一个函数,该函数返回一个对象,该对象包含要暴露给父组件的属性或方法。
  4. 父组件中通过 ref 访问子组件

    • 父组件可以通过 ref 的 current 属性来访问子组件暴露的属性或方法。

四、示例代码

以下是一个简单的示例,展示了如何使用 useImperativeHandle:

import React, { useRef, useImperativeHandle, forwardRef } from 'react';  
  
// 子组件  
const FancyInput = React.forwardRef((props, ref) => {  
  const inputRef = useRef();  
  useImperativeHandle(ref, () => ({  
    focus: () => {  
      inputRef.current.focus();  
    }  
  }));  
  return <input ref={inputRef} type="text" />;  
});  
  
// 父组件  
const App = () => {  
  const fancyInputRef = useRef();  
  return (  
    <div>  
      <FancyInput ref={fancyInputRef} />  
      <button onClick={() => fancyInputRef.current.focus()}>父组件调用子组件的 focus</button>  
    </div>  
  );  
};  
  
export default App;

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

五金件 CNC 加工 —— 为您的产品增添价值

在现代制造业中&#xff0c;五金件作为各种产品的重要组成部分&#xff0c;其质量和精度直接影响着产品的性能和外观。而 CNC(Computer Numerical Control&#xff0c;计算机数控)加工技术的出现&#xff0c;为五金件的生产带来了革命性的变化。它以高精度、高效率和高稳定性的…

031 商品上架-增量同步和全量同步(cubemall-search模块)

文章目录 增量同步全量同步SpuInfoDao.xmlSpuInfo实体类application.ymlpom.xmlSpuInfoController.javaSpuInfoDao.javaSpuInfoEntity.javaSpuInfoRepository.javaSpuInfoServiceImpl.javaCubemallSearchApplication.java 增量同步 1.功能分析 前端页面&#xff0c;点击"…

LabVIEW智能螺杆空压机测试系统

基于LabVIEW软件开发的螺杆空压机测试系统利用虚拟仪器技术进行空压机的性能测试和监控。系统能够实现对螺杆空压机关键性能参数如压力、温度、流量、转速及功率的实时采集与分析&#xff0c;有效提高测试效率与准确性&#xff0c;同时减少人工操作&#xff0c;提升安全性。 项…

智能指针(3)

目录 可能问题五&#xff1a; 问题分析&#xff1a; 答案格式&#xff1a; shared_ptr的模拟实现 部分1&#xff1a;引用计数的设计(分考点1) 代码实现&#xff1a; 部分2&#xff1a;作为类所必须的部分(分考点2) 代码实现&#xff1a; 部分3&#xff1a;拷贝构造函数…

河北工业大学《2021年+2020年980自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《河北工业大学980自控考研资料》的真题篇&#xff0c;真题年份为2004-最新一年。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2021年真题 2020年真题 Part1&#xff1a;2021年…

Data+AI下的数据湖和湖仓一体发展史

DataAI下的数据湖和湖仓一体发展史 前言数据湖的“前世今生”AI时代的救星&#xff1a;湖仓一体湖仓一体实践演进未来趋势&#xff1a;智能化、实时化结语 前言 数据湖&#xff1f;湖仓一体&#xff1f;这是什么高科技新名词&#xff1f; 别急&#xff0c;我们慢慢聊。想象一…

DBeaver导出数据表结构和数据,导入到另一个环境数据库进行数据更新

在工作中&#xff0c;我们会进行不同环境之间数据库的数据更新&#xff0c;这里使用DBeaver导出新的数据表结构和数据&#xff0c;并执行脚本&#xff0c;覆盖另一个环境的数据库中对应数据表&#xff0c;完成数据表的更新。 一、导出 右键点击选中想要导出的数据表&#xff0…

parent参数

一、parent参数 parent参数除了有之前父窗口的界面效果外&#xff0c;还体现了Qt的内存管理策略。parent参数的对象是当前创建的对象的父对象。因此在Qt中存在父对象与子对象的概念&#xff0c;需要注意的是&#xff0c;此处的父子关系与继承无关&#xff0c;至于parent参数有关…

UNION 联合查询

1.UNION ALL联合查询 同样为了演示方便&#xff0c;先向 teacher 表插入多条测试数据&#xff1a; INSERT INTO teacher (name,age,id_number,email) VALUES (姓名一,17,42011720200604077X,NULL), (姓名二,18,42011720200604099X,123qq.com), (姓名三,19,42011720200604020X…

Web 应用防火墙(WAF)

在现代Web应用开发中&#xff0c;Nginx作为反向代理的架构被广泛采用。这种架构具备高性能、易扩展的特点&#xff0c;但也带来了Web层的安全挑战。Web应用防火墙&#xff08;WAF&#xff09;作为专门防御Web应用层攻击的安全措施&#xff0c;能够为此架构增加一层强有力的保护…

服务器托管的优缺点有哪些?

由于数字化程度不断提高&#xff0c;服务器在日常业务中发挥着越来越重要的作用。在大多数情况下&#xff0c;服务器由公司自己维护和管理。但对于一些公司来说&#xff0c;托管服务器(将这些任务交给专业人员)是更好的选择。 关于服务器的优缺点&#xff0c;有一点是明确的&am…

Centos7 安装升级最新版Redis7.4.1

1. 前言 今天阿里云云盾检测出一个redis低版本的漏洞,需要升级到稳定高版本修复漏洞,升级过程遇到了一些坑,特记录分享给大家,原服务器默认yum源安装的gcc 是4.8.5 ,默认安装redis是 3.2.12(如下图): 2.升级GCC 升级新版redis需要更高级的gcc支持,这里我们就选择升级…

打包使用pythn编写的maya插件,使用pyeal打包

1.安装python,注意版本一定要和maya上面的python解释器版本一致 2.安装pyeal使用pycharm或者maya自带的python解释器mayapy.exe 3.如果有别的库&#xff0c;下载安装到你需要的文件夹中&#xff1a; 使用mayapy: "D:\AnZhuangBao\maya2022\2022\maya2022AZ\Maya2022\bin\m…

第二百八十八节 JPA教程 - JPA查询连接OrderBy示例

JPA教程 - JPA查询连接OrderBy示例 以下代码显示如何使用ORDER BY子句和连接条件。 List l em.createQuery("SELECT e " "FROM Project p JOIN p.employees e " "WHERE p.name :project " "ORDER BY e.name").setParameter("pr…

国产AI逆袭!零一万物新模型Yi-Lightning超越 GPT-4o

近日&#xff0c;由全球千万用户盲测投票产生的 AI 模型排行榜公布&#xff0c;国产 AI 模型“Yi-Lightning”逆袭&#xff0c;超越了此前长期占据榜首的 GPT-4。 “Yi-Lightning”模型由国内知名 AI 公司零一万物研发&#xff0c;在多个分榜中均名列前茅&#xff0c;其中数学…

R语言机器学习算法实战系列(六)K-邻近算法 (K-Nearest Neighbors)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍教程下载数据加载R包导入数据数据预处理数据描述数据切割调节参数构建模型预测测试数据评估模型模型准确性混淆矩阵模型评估指标ROC CurvePRC Curve保存模型总结系统信息介绍 K-邻…

从传统到智能,从被动监控到主动预警,解锁视频安防平台EasyCVR视频监控智能化升级的关键密钥

视频监控技术从传统监控到智能化升级的过程是一个技术革新和应用场景拓展的过程。智能视频监控系统通过集成AI和机器学习算法&#xff0c;能够实现行为分析、人脸识别和异常事件检测等功能&#xff0c;提升了监控的准确性和响应速度。这些系统不仅用于传统的安全防护&#xff0…

KPaaS集成平台中怎么创建数据可视化大屏

KPaaS集成平台的数据可视化大屏是什么&#xff1f; 在KPaaS业务集成扩展平台中&#xff0c;数据大屏是一种数据可视化展示工具&#xff0c;它可以帮助企业将复杂的数据以直观、易理解的方式呈现出来&#xff0c;从而提高数据的可读性和价值。数据大屏的主要特点包括&#xff1…

PROFINET开发或EtherNet/IP开发嵌入式板有用于工业称重秤

这是一个真实案例&#xff0c;不过客户选择不透露其品牌名称。稳联技术的嵌入式解决方案助力工业称重设备制造商连接至任意工业网络。多网络连接使得称重设备能够轻松接入不同的控制系统&#xff0c;进而加快产品的上市时间。 我们找到了稳联技术的解决方案。他们成熟的技术与专…

【厦门大学附属第一医院(互联网医院)-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…