创建react项目

在终端输入npx create-react-app xxx创建一个react项目,通过npm start启动该项目.

index.js

react快速过知识点-2024-03-27-10-39-51

StrickMode是一个严格模式,它可以严格的进行功能审查

组件方式

  1. 函数式组件
    • JSX语法,将html+js融合的很深,他每个组件只能返回一个根元素.每个组件都需要正确的闭合
    • 插值功能,通过{}来实现js的内容插入到html中.同样的html的标签可以直接作为值存储在js的类中.而不用在加上字符串符号.
    • 因为每次都只能返回一个根元素,通常的做法是用<></>来进行闭合.当然有些元素需要传入key或者其他属性,这时候就可以使用react提供的Fragment来进行闭合
    • 样式设置.他使用的是className来代替原来的class
      react快速过知识点-2024-03-27-10-53-41
  2. 类组件

组件通信

通过props和解构的方式来实现组件间的通信

传值
react快速过知识点-2024-03-27-10-55-51
他可以单个数据单个数据的传输,也可以直接传进来一个对象,然后再获取对象中的值,都是没问题的
传递组件
而且父组件也可以向子组件传递另一个组件,只要把这个组件放在对应的html中,他就可以正确的展示出来

子组件传递给父组件
这里简单讲就是

  1. 状态提升,将该组件的属性提升到父组件中,然后通过传参的方式让子组件引用父组件的属性
  2. 自定义事件下传,再将修改这个属性的方法封装后传递给子组件,让子组件调用这个方法进行修改.

React的常用Hook

useState
最基础的状态管理

1
2
// 推断类型为 "boolean"
const [enabled, setEnabled] = useState(false);

enabled是状态值,而setEnabled是一个方法,他可以设置你的状态值

useReducer
他使用MVI的开发思路,将意图和状态分开,可以在https://zfxt.top/posts/c7f557a/?highlight=mvi查看关于MVI的相关属性.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import {useReducer} from 'react';

interface State {
count: number
};

type CounterAction =
| { type: "reset" }
| { type: "setCount"; value: State["count"] }

const initialState: State = { count: 0 };

function stateReducer(state: State, action: CounterAction): State {
switch (action.type) {
case "reset":
return initialState;
case "setCount":
return { ...state, count: action.value };
default:
throw new Error("Unknown action");
}
}

export default function App() {
const [state, dispatch] = useReducer(stateReducer, initialState);

const addFive = () => dispatch({ type: "setCount", value: state.count + 5 });
const reset = () => dispatch({ type: "reset" });

return (
<div>
<h1>欢迎来到我的计数器</h1>

<p>计数: {state.count}</p>
<button onClick={addFive}>加 5</button>
<button onClick={reset}>重置</button>
</div>
);
}

这个钩子需要接受两个参数,第一个是接受到意图时,进入某个方法,判断意图并操作,第二个参数是初始状态.
然后使用这个dispatch方法时,需要传递对应的参数来判断需要进行什么操作.
useContext
这就是个全局隐式传递方法的函数,
我们一般传递属性都是通过props,显然的传递我们需要传递的对象,这样往往需要很多的操作,规定父子组件如何传递如何接受,
而使用useContext就可以进行隐式的接受,他是直接在ui树上进行传递的,也就是所有的子组件都可以获取.(包括递归的子组件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import { createContext, useContext } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
return (
<ThemeContext.Provider value="dark">
<Form />
</ThemeContext.Provider>
)
}

function Form() {
return (
<Panel title="Welcome">
<Button>Sign up</Button>
<Button>Log in</Button>
</Panel>
);
}

function Panel({ title, children }) {
const theme = useContext(ThemeContext);
const className = 'panel-' + theme;
return (
<section className={className}>
<h1>{title}</h1>
{children}
</section>
)
}

function Button({ children }) {
const theme = useContext(ThemeContext);
const className = 'button-' + theme;
return (
<button className={className}>
{children}
</button>
);
}

他的步骤就是create,再provider,然后使用useContext获取.
useMemo
进行数据缓存的钩子,用来跳过代价昂贵的重新计算

1
2
3
4
5
6
import { useMemo } from 'react';

function TodoList({ todos, tab, theme }) {
const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
// ...
}

设置只有在某些数据变化时,他才会重新渲染,避免因为其他组建的渲染导致的重新计算
useCollback
与useMemo类似,但是他是缓存函数而不是数据
useRef
react快速过知识点-2024-03-27-11-19-11

  1. 记录状态
    他会记住你当前这个值的状态,并且他不会随着你对该元素的修改而重新渲染页面,也就是不会你的更新不会立刻展示在页面中.
  2. 获取dom
    他的获取方式是.current来获取,他还可以直接获取dom元素的引用,或者其他的子组件,这样他可以直接调用这个原生dom的方法(例如获取input框,然后使用其对焦功能)或者子组件的方法(这样子要求,他才能调用子组件的方法.)
    react快速过知识点-2024-03-27-11-25-04

useEffect
副作用函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function MyComponent() {
useEffect(() => {
// 这里的代码会在每次渲染后执行
});

useEffect(() => {
// 这里的代码只会在组件挂载后执行
}, []);

useEffect(() => {
//这里的代码只会在每次渲染后,并且 a 或 b 的值与上次渲染不一致时执行
}, [a, b]);
return <div />;
}

他的第二个参数,如果是空他就每次渲染都执行.就是监控值,每次修改这个监控值,都会导致他的Effect的调用,

memo方法
如果这个组件的props没有发生变化,他就不会进行重新渲染
react快速过知识点-2024-03-27-11-33-53
他通常与useCallback一起使用,这样子才能实现props的不发生变化(如果不缓存方法的话,他传递的props每次都会变更为一个新方法)