ReactJs笔记摘录

2023-12-12 07:28
文章标签 笔记 摘录 reactjs

本文主要是介绍ReactJs笔记摘录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 前言
    • 目录结构
    • Hook函数
      • useState
      • useEffect
      • useContext
      • useReducer
      • useCallback
      • useMemo
    • JSX语法
      • 根元素与斜杠
      • 使用变量
      • 推荐使用className替代class
      • antd和tailwindcss
    • 组件通信
      • 父传子:props和自定义函数事件
      • 子传父:props.onchange
      • Context
      • 状态管理
      • 结合useContext()和useReducer()实现全局状态共享
    • UI 问题
      • 选择哪个UI框架?
    • 编程规范
    • 参考链接
      • React使用
      • UI框架
      • 组件

前言

以前2018年搞过一段时间react + antd开发,兜兜转转又回到react世界。本文力图记录一些易忘易混的知识点。

目录结构

├─package-lock.json
├─package.json ------------ // 项目配置
├─postcss.config.js ------- // postcss 配置
├─public ------------------ // 公开目录
│ ├─favicon.ico
│ └─index.html
├─README.md ---------- // 项目说明
└─src --------------------- // 源码目录
├─App.tsx --------------- // 根组件
├─assets ---------------- // 静态资源目录
│ └─images -------------- // 图片目录
│     └─logo.png ------ // logo 图片
│ └─svg -------------- // 图标目录
│     └─logo.svg ------ // logo 图片
├─components ------------ // 公共组件目录
│ └─Menu ---------------- // 公共组件
│   ├─index.tsx ---------- // 组件文件
│   └─index.scss ------ // 组件样式
├─constants ---------------- // 项目常量
│ └─index.ts
├─libs ------------------ // 第三方库目录
├─index.tsx --------------- // 主入口
├─router ---------------- // 路由配置
│ └─index.tsx
├─store ----------------- // 状态管理
│ ├─module.ts // 模块
│ └─index.ts // 入口
├─tests ----------------- // 测试目录
├─utils ----------------- // 工具目录
│ ├─a.ts
│ └─index.ts
└─pages ----------------- // 视图目录└─Home ---------------- // 页面组件├─components -------- // 子组件目录│ └─Header│   ├─index.tsx│   └─index.scss└─index.tsx ---------- // 组件主体

Hook函数

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。它们可以帮助我们简化组件的代码并提高代码的可维护性。

Hook 本质就是 JavaScript 函数,但是在使用它时需要遵循两条规则。react官方提供了一个 linter 插件来强制执行这些规则。

  • 只在最顶层使用 Hook。不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层调用他们。
  • 只在 React 函数组件中调用 Hook,也可以在自定义 Hook 中调用其他 Hook。但不要在普通的 JavaScript 函数中调用 Hook。

以下是常见的 Hook 函数:

useState

useState 是一个用于在函数组件中添加状态的 Hook 函数。它接受一个初始状态值,并返回一个数组,其中第一个值为当前状态值,第二个值为更新状态的函数。

import React, { useState } from 'react';function Example() {const [count, setCount] = useState(0);return (<div><p>You clicked {count} times</p><button onClick={() => setCount(count + 1)}>Click me</button></div>);
}

useEffect

useEffect 是一个用于在函数组件中添加副作用的 Hook 函数。它接受一个回调函数和一个依赖数组作为参数。回调函数在组件挂载、更新或卸载时执行。依赖数组中的值发生变化时,也会重新执行回调函数。


import React, { useState, useEffect } from 'react';function Example() {const [count, setCount] = useState(0);useEffect(() => {document.title = `You clicked ${count} times`;}, [count]);return (<div><p>You clicked {count} times</p><button onClick={() => setCount(count + 1)}>Click me</button></div>);
}

useContext

useContext 是一个用于在函数组件中使用 React Context 的 Hook 函数。它接受一个 Context 对象作为参数,并返回该上下文的当前值。

import React, { createContext, useContext } from 'react';const ThemeContext = createContext('light');function Example() {return (<ThemeContext.Provider value="dark"><p>Current theme: {useContext(ThemeContext)}</p></ThemeContext.Provider>);
}

useReducer

useReducer 是一个用于在函数组件中使用状态 reducer 的 Hook 函数。它接受一个 reducer 函数和一个初始状态值作为参数,并返回一个数组,其中第一个值为当前状态值,第二个值为更新状态的函数。

import React, { useReducer } from 'react';function App() {const [state, dispatch] = useReducer(reducer, initialState);return (<div><p>Current state: {state}</p></div>);
}function reducer(state, action) {switch (action.type) {case 'increment':return state + 1;case 'decrement':return state - 1;default:throw new Error();}
}

useCallback

useCallback 是一个用于在函数组件中缓存函数的 Hook 函数。它接受一个函数作为参数,并返回一个缓存函数。如果传入的函数没有发生变化,则返回上次缓存的结果;否则,会重新创建一个新的缓存函数。

import React, { useState, useCallback } from 'react';function Example() {const [count, setCount] = useState(0);const handleClick = useCallback(() => {setCount(count + 1);}, [count]);return (<div><p>You clicked {count} times</p><button onClick={handleClick}>Click me</button></div>);
}

useMemo

useMemo 是一个用于在函数组件中缓存计算结果的 Hook 函数。它接受一个函数作为参数,并返回缓存的结果。如果传入的函数没有发生变化,则返回上次缓存的结果;否则,会重新计算新的结果。

import React, { useState, useMemo } from 'react';function Example() {const [count, setCount] = useState(0);const doubleCount = useMem

JSX语法

根元素与斜杠

注意局部的jsx片段也要加根元素:

return (<div>{items.map((item) => (// 此处只能有一个根元素!!!<>...<div className="flex min-w-fit min-h-fit h-24 w-24 border-4 rounded-md bg-white-100 justify-center">// img后要加斜杠<img loading="lazy" src="http://www.icoolcms.com/cms/link/logo/2384"/></div></>))}</div>
)

使用变量

<img className="logoImg" loading="lazy" src={`http://www.icoolcms.com/cms/link/logo/${item.linkId}`}/>

推荐使用className替代class

className属性是React中使用的属性名称,用于避免与JavaScript的保留关键字class冲突。

antd和tailwindcss

可以在Antd组件中直接使用Tailwindcss类:

<Button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Click me
</Button>

组件通信

React 最推荐的数据交互方式是:props & onChnage。在这种交互方式里:对于一个可视组件 ComponentA,用 props 来向它发送信息,而用 onChange 回调函数来接收 ComponentA 发送的信息。在程序世界里,我们更喜欢把上述「交互方式」称为「接口」,虽然这个「接口」不是我们在面向对象语言里的 interface,但是跟 interface 有着类似的功能。

父传子:props和自定义函数事件

// 父组件
function Money() {const [selected, setSelected] = useState('food');return (<TagsSection value={selected}/>);
}// 子组件
type Props = {//声明props的数据类型value: string;
}const TagsSection: React.FC<Props> = (props) => {const tagName = props.value;return (<div>the tag name is { tagName }</div>);
};

子传父:props.onchange

import React, { useState } from "react";const MyComponent = ({ onChange, initialValue }) => {const [value, setValue] = useState(initialValue);const handleChange = (event) => {setValue(event.target.value);onChange(event.target.value);};return (<inputtype="text"value={value}onChange={handleChange}/>);
};const App = () => {const handleValueChange = (value) => {console.log(`Value changed to: ${value}`);};return (<MyComponent onChange={handleValueChange} initialValue="Initial value" />);
};export default App;

在这个示例中,我们定义了一个名为MyComponent的React组件,它接受一个onChange属性和一个initialValue属性。onChange属性定义了当组件的值发生变化时应该调用的函数,而initialValue属性则定义了组件的初始值。

在MyComponent组件内部,我们使用useState Hook来存储组件的值。然后,我们定义了一个handleChange函数,该函数在用户输入发生变化时被调用。在这个函数中,我们调用setValue来更新组件的值,并调用onChange函数来通知父组件值已更改。

最后,我们定义了一个App组件,该组件使用MyComponent组件,并将handleValueChange函数作为onChange属性的值传递。当组件的值发生变化时,handleValueChange函数将被调用,并输出新的值。

Context

Context 的使用方式:

  • 使用 const xxx = createContext(null) 创建上下文
  • 使用 <xxx.Provider> 圈定作用域
  • 在作用域内使用 useContext(xxx) 来使用上下文

先创建一个 Context 对象:

import React from "react";const ThemeContext = React.createContext();export default ThemeContext;

再创建Provider:

import React from "react";
import ThemeContext from "./ThemeContext";const ThemeProvider = ({ theme }) => {return (<ThemeContext.Provider value={theme}>{/* 这里可以传递其他内容 */}</ThemeContext.Provider>);
};export default ThemeProvider;

再创建Consumer, 它将使用 ThemeContext 上下文来获取 theme 数据

import React from "react";
import ThemeContext from "./ThemeContext";const ThemeConsumer = ({ children }) => {return (<ThemeContext.Consumer>{theme => {// 在这里可以使用 theme 数据return <>{children}</>;}}</ThemeContext.Consumer>);
};export default ThemeConsumer;

连起来:

import React from "react";
import ThemeProvider from "./ThemeProvider";
import ThemeConsumer from "./ThemeConsumer";const theme = {color: "blue",
};const App = () => {return (<ThemeProvider theme={theme}><ThemeConsumer>{({ theme }) => (<div><h1>Theme color: {theme.color}</h1></div>)}</ThemeConsumer></ThemeProvider>);
};export default App;

在这个示例中,我们首先创建了一个 ThemeContext 对象,然后创建了一个 ThemeProvider 组件,它将提供 theme 数据。接下来,我们创建了一个 ThemeConsumer 组件,它将使用 ThemeContext 上下文来获取 theme 数据。最后,我们创建了一个 Root 组件,它将使用 ThemeProvider 组件提供 theme 数据,并使用 ThemeConsumer 组件来获取 theme 数据。

如果不用Consumer,也可以直接使用useContext()获得context数据:

// 使用useContext Hook
const { isLoggedIn, login, logout } = useContext(AuthContext);

状态管理

业内常规的成熟方案一般有:mobx、redux等专门的全局状态管理库,相对而言基本可以覆盖支持所有的复杂业务场景,再也就简单粗暴通过多个Context嵌套来实现共享。Redux 是借鉴 Flux 开发的,它们都是单向数据流,而 MobX 则有所不同,它是基于观察者模式实现。

React18以后的版本内置了useReducer() hook,它是 useState() 的替代品,简单的状态可以直接使用 useState,当我们遇到复杂多层级的状态或者下个状态要依赖上个状态时使用 useReducer() 则非常方便,在配合 Context 与 useContext() 就能实现类似 Redux 库的功能。

  • 当我们项目中复杂程度较低时,建议只用state就可以了
  • 如果仅仅因为存在多层传递数据的场景,不建议使用mobx或redux,可使用context解决
  • 如果仅仅因为夸路由数据共享,不建议使用mobx或redux,可使用context或者路由传参解决
  • 如果业务复杂,需要使用第三方状态管理解决复杂度,看下一条
  • 当项目复杂度一般,小规模团队或开发周期较短、要求快速上线时,推荐使用mobx
  • 当项目复杂度较高,团队规模较大或要求对事件分发处理可监控可回溯时,推荐使用redux,可尝试使用 rematch或@reduxjs/toolkit,减少模板代码

结合useContext()和useReducer()实现全局状态共享

写一个store.tsx:

import React, { createContext, useReducer, useContext } from 'react';const initialState = { count: 0 };function reducer(state, action) {switch (action.type) {case 'increment':return { count: state.count + 1 };case 'decrement':return { count: state.count - 1 };default:throw new Error();}
}const StateContext = createContext();
const DispatchContext = createContext();function useStateStore() {return useContext(StateContext);
}function useDispatchStore() {return useContext(DispatchContext);
}function StoreProvider({ children }) {const [state, dispatch] = useReducer(reducer, initialState);return (<StateContext.Provider value={state}><DispatchContext.Provider value={dispatch}>{children}</DispatchContext.Provider></StateContext.Provider>);
}export { useStateStore, useDispatchStore, StoreProvider };

修改状态:

    import React from 'react';import { useDispatchStore } from './store';function Producer() {const dispatch = useDispatchStore();console.log('header udpate');return (<><button onClick={() => dispatch({type: 'decrement'})}>-</button><button onClick={() => dispatch({type: 'increment'})}>+</button></>);}export default Producer;

消费状态:

    import React from 'react';import { useStateStore } from './store';function Footer() {const state = useStateStore();console.log('footer udpate');return (<p>{state.count}</p>);}export default Footer;

UI 问题

选择哪个UI框架?

除了大名鼎鼎的antd之外,其实还有很多选择。react-bootstrap也是堂堂正正,大部分UI组件都不错。daisyui也冉冉升起。

编程规范

  • 命名:props、变量用小驼峰,组件的文件名用大驼峰
  • 引号:JSX 属性中用双引号("),但是在js里用单引号(')
  • 自闭合标签:在自闭和标签内空一格,如<Foo />,当没有子元素时,最好用自闭合标签
  • 推荐用 ref callback 函数
    useRef() 返回一个具有单个 current 属性 的 ref 对象,并初始化为你提供的初始值
// bad
<Fooref="myRef"
/>// good
<Fooref={(ref) => { this.myRef = ref; }}
/>
  • 用箭头函数关闭局部变量
  • 构造函数里绑定事件处理函数
  • 不要在 React 组件里使用下划线作为内部方法名前缀

参考链接

React使用

  • use-context-selector: 通过选择需要的状态从而规避掉无关的状态改变时带来的渲染开销
  • 如何优雅地使用React Context

UI框架

  • Ant Design: 88k stars,可惜不是基于tailwindcss的。
  • react-bootstrap
  • daisyui: 27k stars
  • material-ui
  • shadcn
  • hyperui
  • flowbite
    Build websites even faster with components on top of Tailwind CSS,Start developing with an open-source library of over 600+ UI components, sections, and pages built with the utility classes from Tailwind CSS and designed in Figma.
  • primefaces
  • preline: Preline UI is an open-source set of prebuilt UI components based on the utility-first Tailwind CSS framework.
  • 基于Tailwindcss的headlessui
  • Evergreen Segment
  • Blueprint React UI
  • Material Design for Bootstrap v5 & v4: Top quality open-source UI Kits
  • Grommet
  • visx
  • Chakra
  • React-admin
    About A frontend Framework for building data-driven applications running on top of REST/GraphQL APIs, using TypeScript, React and Material Design
  • Semantic UI React
  • nextui: Beautiful, fast and modern React UI library.
  • fluent2
  • retool: 要收费
  • React Redux

组件

  • multilevel-dropdown
  • how-create-multilevel-dropdown-menu

这篇关于ReactJs笔记摘录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/483752

相关文章

读书摘录《控糖革命》

又到了每周推荐时间,这周末给大家推荐一本书《控糖革命》。身体是革命的本钱,只有保持健康的身体,才能保证持久的生产力,希望我的读者都可以身体健康,青春永驻。 推荐前,首先申明在《控糖革命》一书中,作者提出了一些颇具争议的观点,这些观点并没有经过系统的科学论证,但这并不妨碍我们从中获取一些有益的控糖建议。作者通过分享作者的个人经验和研究,为我们提供了一种全新的饮食理念,帮助我们更好地控制血糖峰值

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

查看提交历史 —— Git 学习笔记 11

查看提交历史 查看提交历史 不带任何选项的git log-p选项--stat 选项--pretty=oneline选项--pretty=format选项git log常用选项列表参考资料 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的 工具是 git log 命令。 接下来的例子会用一个用于演示的 simplegit

记录每次更新到仓库 —— Git 学习笔记 10

记录每次更新到仓库 文章目录 文件的状态三个区域检查当前文件状态跟踪新文件取消跟踪(un-tracking)文件重新跟踪(re-tracking)文件暂存已修改文件忽略某些文件查看已暂存和未暂存的修改提交更新跳过暂存区删除文件移动文件参考资料 咱们接着很多天以前的 取得Git仓库 这篇文章继续说。 文件的状态 不管是通过哪种方法,现在我们已经有了一个仓库,并从这个仓

忽略某些文件 —— Git 学习笔记 05

忽略某些文件 忽略某些文件 通过.gitignore文件其他规则源如何选择规则源参考资料 对于某些文件,我们不希望把它们纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常它们都是些自动生成的文件,比如日志文件、编译过程中创建的临时文件等。 通过.gitignore文件 假设我们要忽略 lib.a 文件,那我们可以在 lib.a 所在目录下创建一个名为 .gi

取得 Git 仓库 —— Git 学习笔记 04

取得 Git 仓库 —— Git 学习笔记 04 我认为, Git 的学习分为两大块:一是工作区、索引、本地版本库之间的交互;二是本地版本库和远程版本库之间的交互。第一块是基础,第二块是难点。 下面,我们就围绕着第一部分内容来学习,先不考虑远程仓库,只考虑本地仓库。 怎样取得项目的 Git 仓库? 有两种取得 Git 项目仓库的方法。第一种是在本地创建一个新的仓库,第二种是把其他地方的某个