通过Function函数式方式创建React组件-8

在React中,V16版本之前有三种方式创建组件(createClass() 被删除了),之后只有两种方式创建组件。这两种方式的组件创建方式效果基本相同,但还是有一些区别,这两种方法在体如下:
在这里插入图片描述

本节先了解下用Function函数的方式创建React组件,有了上几节的铺垫,所以本节的代码示例部分无用的代码会被过滤掉以节省篇幅。

通过Function函数方式创建组件(推荐)

代码放在一个单独的.js文件中

//HelloReact.js, 组件文件的名称最好也要大写,以方便与非组件的js区分开
function MyComponent() { //名称要大写
    return (
        <img
            src="https://i.imgur.com/MK3eW3As.jpg"
            alt="Katherine Johnson"
        />
    );
}

export default function Gallery() { //发布组件,可以这样来写
    return (
        <section>
            <h1>了不起的科学家</h1>
            <MyComponent />
            <MyComponent />
        </section>
    );
}

调用

import './App.css';
import Gallery  from "./fun/helloReact";

function Fun() {
  return (
    <div className="fun">
      <h3>HelloReact</h3>
      <Gallery/>
    </div>
  );
}

export default Fun;

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
    <Fun/>
  </React.StrictMode>
);
  • 组件名称,必须以大写字母开头
  • return方法需要注意:如果只一行代码,则可以不写(),而且必须和return在同一行。如果有多行代码必须写(),否则没有括号包裹的话,任何在 return 下一行的代码都 将被忽略!
  • 不要在组件中嵌套组件定义,因为会严重影响性能;

核心属性

props

函数式组件定义参数会有两种写法,用哪一种都可以:

语法格式
  • 第一种:明确定义多个参数,{ }
//这种方式,一定要注意参数外面的的 {}
function Avatar({ person, size }) {
  // ...
}
  • 第二种
function Avatar(props) {
  let person = props.person;
  let size = props.size;
  // ...
}
  • 以上两种参数定义的方式的调用方式相同
<Avatar
    person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
    size={100}
/>

针对以上两种传值时还可以有如下扩展

设置默认值
export function Avatar1({ person, size=100 }) {
   return (
       <div>{JSON.stringify(person)}, {size}</div>
   );
}
export default function Form({status = 'empty'}) {
    if (status === 'success') {
        return <h1>That's right!</h1>
    }
    return (
        <>
            <h2>City quiz</h2>
        </>
    )
}
传递子元素

注意使用内置的children属性

export function Avatar3(props) {
    return (
        <div>{props.children}</div>
    );
}

//调用方式
<Avatar3>
    <p>我是嵌套组件</p>
</Avatar3>

唯一需要注意的是,props是不可变的,如果是可变的参数要放置在state中。

ref

使用 ref 操作Html原生DOM

由于 React 会自动处理更新 DOM 以匹配你的渲染输出,因此你在组件中通常不需要操作 DOM。但是,有时你可能需要访问由 React 管理的 DOM 元素 —— 例如,让一个节点获得焦点、滚动到它或测量它的尺寸和位置。在 React 中没有内置的方法来做这些事情,所以你需要一个指向 DOM 节点的 ref 来实现。

refref.current

import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        聚焦输入框
      </button>
    </>
  );
}

useRef()返回一个对象,该对象有一个名为 current 的属性。最初,myRef.current 是 null。当 React 为这个<div>创建一个 DOM 节点时,React 会把对该节点的引用放入 myRef.current。然后,你可以从 事件处理器 访问此 DOM 节点,并使用在其上定义的内置浏览器 API。

使用 ref 操作自定义组件DOM

将 ref 放在你自己的组件上,默认情况下你会得到 null,而且会得到一个错误
Cannot read properties of null (reading 'focus') 。比如下面的代码:

import { useRef } from 'react';

function MyInput(props) {
  return <input {...props} />;
}

export default function MyForm() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        聚焦输入框
      </button>
    </>
  );
}

但可以用另一种机制forwardRef解决,MyInput 组件是使用 forwardRef 声明的。 这让从上面接收的 inputRef 作为第二个参数 ref 传入组件,第一个参数是 props 。MyInput 组件将自己接收到的 ref 传递给它内部的 <input>就起作用了。

import { forwardRef, useRef } from 'react';

const MyInput = forwardRef((props, ref) => {
  return <input {...props} ref={ref} />;
});

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        聚焦输入框
      </button>
    </>
  );
}

事件交互

绑定事件

普通的事件绑定,代码一般写在最上面。这里的handleClick也可以做为一个参数,由父组件传入。

export default function Button() {
    function handleClick() {
        alert('你点击了我!');
    }

    return (
        <button onClick={handleClick}>
            点我
        </button>
    );
}

其它的简单写法,如果不是由父组件传入时,不是太推荐这种写法。因为只有当函数体较短时,内联事件处理函数会很方便。

<button onClick={function handleClick() {
  alert('你点击了我!');
}}>

<button onClick={() => {
  alert('你点击了我!');
}}>

需要注意{handleClick}后面没有(),如果写了括号,在加载组件时就会在渲染时执行而在点击时不会执行。

事件传参

主要用了这个特性,<button onClick={(e)=>handleClick1(e,'tt')}>

export default function Button() {
    function handleClick1(e, args ) {
        console.log(args);
        console.log(e.target);
    }

    return (
        <div>
            <button onClick={handleClick}>
                点我
            </button>
            <button onClick={(e)=>handleClick1(e,'tt')}>
                点我带参数
            </button>
        </div>
    );
}

发送请求

采用内置的post函数即可

 post('/analytics/event', { eventName: 'visit_form' });

将事件处理函数作为 props 传递

就是把点击事件定义在组件外面,这样复用度会更高,下面是一个简单的工具栏的例子:

function Button({ onClick, children }) {
  return (
    <button onClick={onClick}>
      {children}
    </button>
  );
/* 注意这种替代写法
  <button onClick={e => {
    e.stopPropagation();
    onClick();
  }}>
*/
}

function PlayButton({ movieName }) {
  function handlePlayClick() {
    alert(`正在播放 ${movieName}`);
  }

  return (
    <Button onClick={handlePlayClick}>
      播放 "{movieName}"
    </Button>
  );
}

export default function Toolbar() {
  return (
    <div>
      <PlayButton movieName="魔女宅急便" />
    </div>
  );
}

事件传播和默认行为

这是JS的一个特性,即事件会沿着DOM树向上“冒泡”或“传播”:它从事件发生的地方开始,然后沿着树向上传播。这种机制有好处有坏处,好处是我们可以根据这种特性自动调用外层组件的相同方法。,另一个就是事件捕获,捕获事件对于路由或数据分析之类的代码很有用。

function handleClick(e) {
      e.stopPropagation(); //防止事件传播
      alert('你点击了我!');
  }

另一个相关的就是阻止默认行为,比如表单的onSubmit事件,e.preventDefault();

组件间通信

父子间数据传递

对于父子组件就不细说了,可以查看前一篇文章:

  • 父到子:通过props传递参数;
  • 子到父:通过回调函数更改state通信

跨级组件间通信

通常来说,你会通过 props 将信息从父组件传递到子组件。但是,如果你必须通过许多中间组件向下传递 props,或是在你应用中的许多组件需要相同的信息,传递 props 会变的十分冗长和不便。Context 允许父组件向其下层无论多深的任何组件提供信息,而无需通过 props 显式传递。
在这里插入图片描述
Context 让父组件可以为它下面的整个组件树提供数据,大概原理如下:
在这里插入图片描述

  • 声明 – LevelContext.js’
import { createContext } from 'react';
export const LevelContext = createContext(1); //LevelContext就是参数名,后面1也可以换成一个复杂的对象
  • 使用 – Heading.js
import { useContext } from 'react';
import { LevelContext } from './LevelContext.js';
const level = useContext(LevelContext);
  • 提供-- Section.js
    上面其实就完成了一个使用过程,相当于一个全局变量,但还没有传值这么一块。上面代码leavl=1,加了Section.js后level=level的值。
import { LevelContext } from './LevelContext.js';

export default function Section({ level, children }) {
  return (
    <section className="section">
      <LevelContext.Provider value={level}> {/*参数*/}
        {children}
      </LevelContext.Provider>
    </section>
  );
}

//调用
<Section level={2}>

这告诉 React:“如果在<Section>组件中的任何子组件请求 LevelContext参数,给他们这个 level(2)”。组件会使用 UI 树中在它上层最近的那个 <LevelContext.Provider> 传递过来的值。

State

React.useState
state的作用不用多说了,使用方式如下:

import { useState } from 'react';

export default function GalleryWall() {
    //index 是一个 state 变量,setIndex 是对应的 setter 函数, 后面的0表示index变量的默认值,定义成const的原因也是为了限制只能通过setIndex()方法来修改,不要直接用==来赋值。
    const [index, setIndex] = useState(0);

    function handleClick() {
        //调用 setIndex 方法相当于改变了state中的数据,然后会自动调用render()函数渲染页面。
        setIndex(index + 1);
    }
    return (
       <div>{index}</div>
    );

在 React 中,useState 以及任何其他以“use”开头的函数都被称为 Hook,作用是可以让组件中使用不同的 React 特性,本质是个函数,但不建议在条件语句、循环语句或其他嵌套函数内调用 Hook。因为这样会比较影响性能。

多个state的写法同上类似

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);
}

使用state重绘UI

这个例子主要是利用了state值变化会自动重新渲染组件的能力,点击按钮后会替换为一个div。

import {useState} from "react";

export default function Repaint() {
    const [isRepainting, setIsRepainting] = useState(false);

    if (isRepainting){
        return(
            <div>重绘了组件UI</div>
        )
    }
    function handleClick(e) {
        setIsRepainting(true); 
    }

    return (
        <div>
            <button onClick={handleClick}>
                点我重绘
            </button>
        </div>
    );
}

state的批处理

这主要是处理特殊情况,原因是state在一次渲染过程中间其值不会变化的。比如下面两行代码。

const [number, setNumber] = useState(0);
//最终值为1,因为在一次渲染过程中虽然调用了三次,但其number值始终为0
setNumber(number + 1);
setNumber(number + 1);
setNumber(number + 1);

//最终值为3,下面是一个固定写法,React的一个队列功能,其中n为自定义的一个变量名
setNumber(n => n + 1);
setNumber(n => n + 1);
setNumber(n => n + 1);

更新 state 中的对象

state 中可以保存任意类型的 JavaScript 值,包括对象。但是,你不应该直接修改存放在 React state 中的对象。相反,当你想要更新一个对象时,你需要创建一个新的对象(或者将其拷贝一份),然后将 state 更新为此对象。应该将 state 视为只读的。

const [position, setPosition] = useState({ x: 0, y: 0 });:表示position的初始值为{ x: 0, y: 0 }。

不能直接改变postion的值,应该像下面这样

setPosition({
  x: e.clientX,
  y: e.clientY
});

或是使用如下语法复制一个对象(下面有简写方式):

const nextPosition = {};
nextPosition.x = e.clientX;
nextPosition.y = e.clientY;
setPosition(nextPosition);

如果是表单时,可采用下面的方法,即统一参数名,然后用event.target.name这种方式来更新

import { useState } from 'react';

export default function Form() {
  const [person, setPerson] = useState({
    firstName: 'Barbara',
    lastName: 'Hepworth'
  });

  function handleChange(e) {
    setPerson({
      ...person,
      [e.target.name]: e.target.value
    });
  }

  return (
    <>
      <label>
        First name:
        <input
          name="firstName"
          value={person.firstName}
          onChange={handleChange}
        />
      </label> {/**省略lastName/}
      <p>
        {person.firstName}{' '}
      </p>
    </>
  );
}

更新state中的数组

需要注意两个方法:

  • slice 让你可以拷贝数组或是数组的一部分。
  • splice 会直接修改 原始数组(插入或者删除元素)(不能用)

以下是一个添加的例子,注意代码的执行流程:

const [name, setName] = useState('');
const [artists, setArtists] = useState([]);

let nextId = 0;

return (
    <>
        <h1>振奋人心的雕塑家们:</h1>
        <input
            value={name}
            onChange={e => setName(e.target.value)}
        />
        <button onClick={() => {
            setArtists([
                ...artists,
                { id: nextId++, name: name }
            ]);
        }}>添加</button>
        <ul>
            {artists.map(artist => (
                <li key={artist.id}>{artist.name}</li>
            ))}
        </ul>
    </>
);

使用展开…语法复制对象

上面的例子可用下面代码来书写,如果没有后面的x: e.clientX就是一个复制。

setPosition({
  ...position, // 复制上一个 position 中的所有字段
  x: e.clientX // 但是覆盖 x 字段 
});

但需要注意 … 展开语法本质是是“浅拷贝”——它只会复制一层。这使得它的执行速度很快,但是也意味着当你想要更新一个嵌套属性时,你必须得多次使用展开语法。

const [person, setPerson] = useState({
  name: 'Niki de Saint Phalle',
  artwork: {
    title: 'Blue Nana',
    city: 'Hamburg',
    image: 'https://i.imgur.com/Sd1AgUOm.jpg',
  }
});

const nextArtwork = { ...person.artwork, city: 'New Delhi' };
const nextPerson = { ...person, artwork: nextArtwork };
setPerson(nextPerson);

//推荐
setPerson({
  ...person, // 复制其它字段的数据 
  artwork: { // 替换 artwork 字段 
    ...person.artwork, // 复制之前 person.artwork 中的数据
    city: 'New Delhi' // 但是将 city 的值替换为 New Delhi!
  }
});

使用 Immer 插件语法复制对象

npm install use-immer
用 import { useImmer } from 'use-immer' 替换掉 import { useState } from 'react'

import { useImmer } from 'use-immer';

export default function Form() {
    const [person, updatePerson] = useImmer({
        name: 'Niki de Saint Phalle',
        artwork: {
            city: 'Hamburg',
        }
    });

    function handleNameChange(e) {
        updatePerson(draft => {
            draft.name = e.target.value;
        });
    }

    function handleCityChange(e) {
        updatePerson(draft => {
            draft.artwork.city = e.target.value;
        });
    }

    return (
        <>
            <label>
                Name:
                <input value={person.name} onChange={handleNameChange} />
            </label>
            <label>
                City:
                <input
                    value={person.artwork.city}
                    onChange={handleCityChange}
                />
            </label>
            <p>
                {person.name} (located in {person.artwork.city})
            </p>
        </>
    );
}
const initialList = [
  { id: 0, title: 'Big Bellies', seen: false },
  { id: 1, title: 'Lunar Landscape', seen: false },
  { id: 2, title: 'Terracotta Army', seen: true },
];
const [myList, updateMyList] = useImmer(
  initialList
);

//id=序号,nextSeen=true|false,即单值框的值,
function handleToggleMyList(id, nextSeen) {
  updateMyList(draft => {
    const artwork = draft.find(a =>
      a.id === id
    );
    artwork.seen = nextSeen;
  });
}
  //ItemList是一个另外封装的组件
  return (
    <>
      <h1>艺术愿望清单</h1>
      <h2>我想看的艺术清单:</h2>
      <ItemList
        artworks={myList}
        onToggle={handleToggleMyList} />
    </>
  );

在这里插入图片描述

对 state 进行保留和重置

相同位置的相同组件会使得 state 被保留下来。这是React的一个特性,这就造成了一个问题,比如像书本这样的应用,翻页时会显示在同样的位置,如果在前一页做了操作,如果state会保留那么这个状态会带到下一页上去,就会乱套了。

对 React 来说重要的是组件在 UI 树中的位置,而不是在 JSX 中的位置!

保留

import { useState } from 'react';

export default function App1() {
    const [isFancy, setIsFancy] = useState(false);
    return (
        <div>
            {isFancy ? (
                <Counter isFancy={true} />
            ) : (
                <Counter isFancy={false} />
            )}
            <label>
                <input
                    type="checkbox"
                    checked={isFancy}
                    onChange={e => {
                        setIsFancy(e.target.checked)
                    }}
                />
                使用好看的样式
            </label>
        </div>
    );
}

function Counter({ isFancy }) {
    const [score, setScore] = useState(0);
    const [hover, setHover] = useState(false);

    let className = {color:"red"};
    if (isFancy) {
        className = {color:"yellow"};;
    }

    return (
        <div
            style={className}
            onPointerEnter={() => setHover(true)}
            onPointerLeave={() => setHover(false)}
        >
            <h1>{score}</h1>
            <button onClick={() => setScore(score + 1)}>
                加一
            </button>
        </div>
    );
}

在这里插入图片描述
当切换颜色时,上面的数字会保留之前的样式,这是因为 相同位置的相同组件会使得 state 被保留下来 。因为React认为是同一个组件。

key使用重置

如果把上面的代码,改成如下代码,则每次切换颜色都会归0,因为用key了表示是不同的组件,不能保留的原因是重新绘制时把组件给删除了,此时状态也消失了。如果需要保留的话把它隐藏即可。或是把状态提升到父类中,在重新绘制时再以参数的方式传递进来。

{isFancy ? (
       <Counter key="blue" isFancy={true} />
   ) : (
       <Counter key="yellow" isFancy={false} />
)}

用useReducer替换useState集中状态变化函数

对于拥有许多状态更新逻辑的组件来说,过于分散的事件处理程序可能会令人不知所措。对于这种情况,你可以将组件的所有状态更新逻辑整合到一个外部函数中,这个函数叫作 reducer。

//替换对象
import { useReducer } from 'react';

/*
* action:action自定义的对象
* currState:当前状态
* */
function tasksReducer(currState, action) {
    switch (action.type) {
        case 'added': {
            console.log(action.id);
            return currState+1;
        }
        case 'deleted': {
            return currState-1;
        }
        default: {
            throw Error('未知 action:' + action.type);
        }
    }
}

export default function UseState() {
    //定义状态, tasksReducer为自定义的函数
    const [score, dispatch] = useReducer(tasksReducer, 0);

    function added(){
        // "action" 对象:它是一个普通的 JavaScript 对象。它的结构是由你决定的
        dispatch({
            type: 'added',
            id:11  //多余的参数,直接封装在action中
        })
    }
    function deleted(){
        dispatch({
            type: 'deleted',
        })
    }
    return (
        <div>
            <input type="text" value={score}/>
            <button onClick={added} >+1</button>
            <button onClick={deleted} >-1</button>
        </div>
    );
}

因为 Reducer 和 Context 就是操作state的,所以可以结合这两个元素在一起,提供一个更复杂的状态管理,比如下面这样的示例代码:

export function TasksProvider({ children }) {
  const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);

  return (
    <TasksContext.Provider value={tasks}>
      <TasksDispatchContext.Provider value={dispatch}>
        {children}
      </TasksDispatchContext.Provider>
    </TasksContext.Provider>
  );
}

严格模式

严格模式主要用于开发环境帮助找到错误,在生产环境下不生效。在严格模式下开发时,它将会调用每个组件函数两次。通过重复调用组件函数,严格模式有助于找到违反一些规则的代码,比如不纯粹的组件等。

import React from 'react';
root.render(
  <React.StrictMode>  {/* 严格模式 */}
    <App />
    <Fun/>
  </React.StrictMode>
);

组件导出和导入

可以直接写成下面这样的代码,因为我们的宗旨是构建小而美的组件,所以下列的代码完全合理:

//helloReact.js
export default function Gallery(){ }
export function MyComponent(){ }
语法导出语句导入语句
默认export default function Button() {}import Button from ‘./Button.js’; 这里的Button名字可以自定义
具名export function Button() {}import { Button } from ‘./Button.js’;
  • 最后的.js可以省略
  • 同一文件中,有且仅有一个默认导出,但可以有多个具名导出!
  • 默认导出时,在导入时的名字可以自定义,但具名导入时必须和导出的名字一样,但具名导出一般多用于工具类的时候会比较多,比如下面这个工具类:
export function getImageUrl(person, size = 's') {
  return (
    'https://i.imgur.com/' +
    person.imageId +
    size +
    '.jpg'
  );
}

特殊用法

以下这些用法有时会用不到,但还是需要了解下

纯数据组件

//quotes.js
export default [
  "Don’t let yesterday take up too much of today.” — Will Rogers",
  "Ambition is putting a ladder against the sky.",
  "A joy that's shared is a joy made double.",
  ];

//InspirationGenerator.js
import quotes from './quotes';
export default function InspirationGenerator({children}) {
    const quote = quotes[index];

    return (
        <>
            <FancyText text={quote} />
        </>
    );
}  

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

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

相关文章

机器学习算法手撕(一):KD树

import math import matplotlib.pyplot as pltclass Node:def __init__(self, data, leftNone, rightNone):self.data dataself.left leftself.right right# 创建KDTree类 class KDTree:def __init__(self, k):self.k kdef create_tree(self,dataset,depth):if not dataset…

【DAOS】daos client和dfuse 是什么?

目录 什么是daos client dfuse 是什么 dfuse 和 FUSE 之间的关系 什么是daos client &#xff08;参加&#xff1a;DAOS: A Scale-Out High Performance Storage Stack for Storage Class Memory | SpringerLink&#xff09; DAOS Client是一个与应用程序集成的库。 从堆栈…

堆(建堆算法,堆排序)

目录 一.什么是堆&#xff1f; 1.堆 2.堆的储存 二.堆结构的创建 1.头文件的声明&#xff1a; 2.向上调整 3.向下调整 4.源码&#xff1a; 三.建堆算法 1.向上建堆法 2.向下建堆法 四.堆排序 五.在文件中Top出最小的K个数 一.什么是堆&#xff1f; 1.堆 堆就…

【docker】仓库harbor的部署

harbor介绍 Harbor 是一个用于存储和管理 Docker 镜像的开源仓库。它提供了一系列的功能&#xff0c;比如用户管理、访问控制、镜像管理、日志审计和安全扫描等。Harbor 可以作为私有仓库来使用&#xff0c;也可以与公有仓库&#xff08;如 Docker Hub&#xff09;集成使用。 …

03.tomcat环境搭建

上传软件包 JDK #man bash #PATH 存放命令的路径 ## ls #加入环境变量&#xff0c;注意&#xff1a;EOF的单引号的意思就是追加到文件中的内容带有变量的不做解析&#xff0c;否则会被解析 cat >>/etc/profile <<EOF export JAVA_HOME/application/jdk export PAT…

华为OD机试 - 寻找最富裕的小家庭(Java 2024 C卷 100分)

华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测试…

Python 开心消消乐

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

M00238-固定翼无人机集群飞行仿真平台MATLAB完整代码含效果

一个小型无人机集群仿真演示平台&#xff0c;使用matlab和simulink搭建。 给出的例子是5架的&#xff0c;当然如果你愿意花时间&#xff0c;也可以把它扩展到10架&#xff0c;20架甚至更多。 输入&#xff1a;5架飞机的规划路径 输出&#xff1a;每架无人机每个时刻的13个状态量…

【模拟面试问答】深入解析力扣164题:最大间距(桶排序与排序方法详解)

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

【C++】从零开始构建红黑树

送给大家一句话&#xff1a; 日子没劲&#xff0c;就过得特别慢&#xff0c;但凡有那么一点劲&#xff0c;就哗哗的跟瀑布似的拦不住。 – 巫哲 《撒野》 &#x1f30b;&#x1f30b;&#x1f30b;&#x1f30b;&#x1f30b;&#x1f30b;&#x1f30b;&#x1f30b; ⛰️⛰️…

指针(6)

1. sizeof和strlen的对比 1.1 sizeof 在学习操作符的时候&#xff0c;我们学习了 sizeof &#xff0c; sizeof 计算变量所占内存内存空间大小的&#xff0c;单位是字节&#xff0c;如果操作数是类型的话&#xff0c;计算的是使⽤类型创建的变量所占内存空间的大小。 sizeof 只…

leetcode:计数质数

class Solution { public:// 如果 x 是质数&#xff0c;那么大于 x 的 x 的倍数 2x,3x… 一定不是质数int countPrimes(int n) {vector<int> isPrime(n, 1);int ans 0;for (int i 2; i < n; i) {if (isPrime[i]) {ans 1;if ((long long)i * i < n) {for (int j …

Linux内核重置root密码

Ubuntu 首先重新启动Ubuntu系统&#xff0c;然后快速按下shift键&#xff0c;以调出grub启动菜单在这里我们选择第二个&#xff08;Ubuntu高级选项&#xff09;&#xff0c;选中后按下Enter键 选择最高的Linux内核版本所对应的recovery mode模式&#xff0c;按e键编辑启动项 在…

C语言 | Leetcode C语言题解之第113题路径总和II

题目&#xff1a; 题解&#xff1a; int** ret; int retSize; int* retColSize;int* path; int pathSize;typedef struct {struct TreeNode* key;struct TreeNode* val;UT_hash_handle hh; } hashTable;hashTable* parent;void insertHashTable(struct TreeNode* x, struct Tr…

数据结构——链表——模板类实现双向链表——先完成再完美——持续更

链表&#xff1a;概念&#xff0c;实现&#xff0c;《数据结构》这里实现是基于模板的 C语言基础&#xff0c;指针&#xff0c;引用。模板。《CPrimer》有些进阶用法放在语言学习的目录 LeetCode应用&#xff0c;会更新在LeetCode150&#xff0c;目前这个系列先暂停&#xff0c…

【PB案例学习笔记】-09滚动条使用

写在前面 这是PB案例学习笔记系列文章的第8篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gitee…

云界洞见——基于移动云云数据库MySQL应用实践

目录 简介1 新手入门1.1 创建MySQL实例1.2 公网连接MySQL实例 2 操作指南2.1 创建数据库2.2 数据备份设置2.3 日志管理2.4 监控告警2.5 代码审计 3 应用场景4 总结 如今&#xff0c;大型企业如金融企业和银行等&#xff0c;在下一代的微服务架构转型要求下&#xff0c;需要基础…

C++ prime 第五版 第14章 重载运算与类型转换

一、基本概念 重载的运算符是具有特殊名字的函数&#xff1a;它们的名字由关键字operator和其后要定义的运算符号共同组成。和其他函数一样&#xff0c;重载的运算符也包含返回类型、参数列表以及函数体。 我们不能为内置类型的运算对象重定义运算符。对于一个运算符函数来说&…

【Week-R1】RNN实现心脏病预测,基于tensorflow框架

文章目录 一、什么是RNN&#xff1f;二、准备环境和数据2.1 导入数据 三、构建模型四、训练和预测五、其他&#xff08;1&#xff09;sklearn模块导入报错&#xff1a;ModuleNotFoundError: No module named sklearn&#xff08;2&#xff09;优化器改为SGD&#xff0c;accurac…

MySQL--备份恢复

目录 一、备份恢复的工作职责 1.备份的时间周期 2.备份的方式 3.恢复方案 4.检查备份 5.定期恢复演练 6.故障恢复策略 7.迁移升级 二、逻辑备份工具--mysqldump 1.介绍 2.使用场景 3.mysqldump命令的参数介绍 1&#xff09;全备&#xff1a; 2&#xff09;单库或…