最后
文章到这里就结束了,如果觉得对你有帮助可以点个赞哦
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
// 从 react 的包当中引入了 React。
//只要你要写 React.js 组件就必须引入React,
//因为react里有一种语法叫JSX,要写JSX,就必须引入React
import React from 'react'
//ReactDOM 可以帮助我们把 React 组件渲染到页面上去,
//没有其它的作用了。它是从 react-dom 中引入的,
//而不是从 react 引入。
import ReactDOM from 'react-dom'
//从APP.js中引入函数APP
import APP from './APP'
//通过构建DOM树
const root=ReactDOM.createRoot(
document.getElementById('root'))
root.render( //render 对根组件(DOM树)进行渲染
// <React.StrictMode></React.StrictMode> 该标签是
//React中一种标准的模式,用于排错,可以省略
<React.StrictMode>
<h1>欢迎进入React的世界</h1>
<APP />
</React.StrictMode>
//<APP /> 该标签用于调用APP.js中的APP函数
)
APP.js
//构建函数,该函数用于页面渲染
function APP()
{
const divContent="标题内容"
const divTitle="标题"
return(
<div title={divTitle}>{divContent}</div>
//{divContent}在标签div内容中的插值
//{divTitle}在标签div属性中的插值
)
//当返回多行内容时,return后面必须加()
//return 后面只能返回一个标签,若有多个标签要返回,
//需要在最外面套一个共同的父标签
//也可以采用下面两种方法:
//1.<></>在外面套一个空标签
//2.<Fragment></Fragment> 在外面套一个Fragment标签
}
export default APP;
map 循环遍历
render() {
const data = ['apple', 'banana', 'orange'];
const componentList = data.map((item, index) => {
return <Component key={index} data={item} />;
});
return (
<div>
{componentList}
</div>
);
}
在这个例子中,data
数组包含了三个水果名称,我们使用map()
方法遍历data
数组,并针对每个元素创建一个<Component>
组件,通过key
属性来唯一标识每个组件(下标index
标识),同时将当前元素作为data
属性传递给组件。最后,将生成的组件列表放在<div>
容器中进行渲染。
需要注意的是,使用
map()
方法时,需要给每个生成的元素指定一个唯一的key
属性,以便React能够准确地进行组件的识别和更新
事件
React 事件的命名采用小驼峰式(camelCase),而不是纯小写。如点击事件onClick
使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串
function hello (e) { //事件函数
console.log("哈喽我是点击事件",e);
}
//e 中存放的是该事件的一些信息,如鼠标坐标
function A () {
return (
<div>
<button onClick={this.hello}>你好</button>
</div>
//onClick后面跟上事件对应的方法名
)}
React Hooks(钩子函数)
useState 状态处理
useState
设置出的变量,叫状态变量,该变量的改变会引起页面的自动刷新
//构建函数,该函数用于页面渲染
function APP()
{
const [content,setcontent]=useState("当前内容")
//设置状态变量,并设置其初始值,返回值为两个变量,
//一个用于读取,一个用于修改
//参数content用来读取该状态变量的当前值,参数setcontent
//用来修改值
function handle(e) //事件函数
{
setcontent("修改后的新内容");
//将setcontent对应的状态变量值进行修改
//修改方式:用传入的值来替换原来的值
//因此,若状态变量是一个对象,则修改时需要将所有成员
//变量都书写出来
//若成员变量太多,可以将对象展开
//展开的代码属性形式: `...读取状态变量值的参数名,`
//在这后面再对其中部分数据进行修改
//(重复声明的变量,后面值会覆盖前面值)
console.log("点击了按钮",e);
//e 中存放的是该事件的一些信息,如鼠标坐标
}
return(
<Fragment>
<div >{content}</div>
<button onClick={handle}>按钮</button>
</Fragment>
);
}
useContext逐层传递
CreateContext
设置出的变量,该变量能够逐层传递,从而由此可以改变每一层的Props(属性)
const levelContent=CreateContent(5)
//使用CreateContent()设置了一个Context变量,并为其设初值
//………………
const level=useContext(levelContent)
//获取对应Content变量的值,该值由上层组件中距离当前组件最近的
//`<MyContext.Provider>` 的 `value prop(属性)` 决定。
//若已经是最高层了,则对应的Context变量值由其初值决定
<levelContext.Provider value={level+1}>
…………
</levelContext.Provider>
useReducer统一管理
useReducer
是一个 React hooks,它允许你在组件中使用状态管理。useReducer
接受两个参数:一个函数作为计算状态的 reducer(状态管理函数
),以及初始状态(初始值)。reducer 函数接收 state(状态变量
) 和 action(对该状态变量进行什么操作
) 作为参数,并返回一个新的 state(状态变量
)。
useReducer
还提供了一个函数 useReducerPayload
,它可以直接在组件中获取由 action 传递的属性。
定义一个 reducer 函数,它接收 state
和 action
作为参数:
const counterReducer = (state = 0, action) => {
//action.type 表示对state状态变量操作的类型
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
};
在组件中使用 useReducer
和 useReducerPayload
:
const Counter = () => {
const [state, setState] = useReducer(counterReducer,0);
//useReducer()参数1是该状态变量对应的状态管理函数,
//参数2是状态变量的初始值
//返回值为 state 状态变量,setState 状态管理函数触发函数
const increment = () => {
setState({ type: 'INCREMENT' });
//传入操作类型
};
const decrement = () => {
setState({ type: 'DECREMENT' });
};
const getPayload = () => {
return state;
};
return (
<div>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
<p>Counter: {getPayload()}</p>
</div>
);
};
在这个示例中,我们定义了一个简单的计数器组件,它使用了
useReducer
来管理状态。我们定义了一个名为counterReducer
的 reducer 函数,它根据 action 的类型来更新 state。然后,我们使用useReducer
获取 state 并将其传递给组件。我们还定义了两个函数increment
和decrement
,它们分别用于增加和减少计数。最后,我们使用useReducerPayload
函数直接获取 state,并在组件中显示它。
useRef获取状态
useRef
是一个 React hook,它允许你在函数组件中创建一个 ref。ref 是一个指向 DOM 元素的引用,你可以使用它来记录 DOM 元素的状态。ref 不会被渲染,所以它们不会出现在最终的 DOM 结构中。
在组件中使用 useRef
:
const Counter = () => {
const [state,setstate]=useState(2)
const count = useRef();
//设置一个叫count的ref
count.current=state;
//将当前状态变量的值赋值给count
const increment = () => {
state++;
};
const decrement = () => {
state--;
};
//最终结果是点击按钮,状态变量state不断在改变,但count的值
//不变,想要改变count的值需要操作count.current
return (
<div>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
<p>Counter: {count.current}</p>
</div>
);
};
注意,useRef
仅在函数组件中有效
Ref不仅可以获取值,还可以获取标签:
const inputEl = useRef(null)
//设置Ref变量并与input标签关联
const handleFocus = () => {
inputEl.current.focus()
//获取input标签,并调用其focus()方法,使其获得焦点
//(即选中输入框)
}
return (
<p>
<input ref={inputEl} type="text" />
{/\*将ref变量inputEl与该输入框关联\*/}
<button onClick={handleFocus}>按钮</button>
</p>
)
Ref还可以获取一个组件:
如上图所示,组件APP
中有一个子组件Child
, 设置一个ref 变量childRef
与其关联,同时,子组件Child
函数需要使用forwardRef()
来处理,以方便子组件与Ref变量关联,这样在父组件中就可以通过操作childRef
来直接使用该子组件了
父组件还可以通过Ref变量
使用子组件中的部分方法
:
如上图所示,子组件可以通过参数ref
来接收与之关联的Ref变量
,通过useImperativeHandle()
来将其中的子组件方法提供给父组件使用。
- 参数1是与该组件关联的
Ref变量
- 参数2是一个函数,该函数返回值必须是一个对象,因此才会有
{}
的出现
下图是父组件App
使用子组件Child
中的方法myFn
:
useEffect 副作用函数
useEffect()
设置的函数可以在非用户触发时自动执行
,默认是在组件渲染开始时进行,每刷新页面一次,执行一次
useEffect()
:
- 参数1是要执行的函数
- 参数2是个数组,其中存放触发函数执行的变量(
变量改变,函数执行
),若数组为空,则没有变量能促发函数执行(页面刷新除外
),该参数可以缺省,缺省则页面刷新一次,执行一次
useMemo 数据缓存
如上图所示,通过useMemo可以将函数对应的返回值进行缓存。
- 参数1 函数,该函数的返回值会进行缓存,
result
中存放着函数的返回值 - 参数2 是个数组,
当其中对应的变量发生变化时,缓存中的值才会更新
,即函数会重新执行
useCallback函数缓存
如上图所示,Button
是一个子组件,传入的参数onClick
是一个函数,该组件通过memo()
变为了一个记忆组件,即只要传入的Props不变,子组件就不会重新执行
如上图所示,通过useCallback()
将对应函数进行缓存,只有当参数2([])
中的变量改变时,对应的函数才会重新执行。
展开语法
通过...参数名
可以将对象性质的变量展开
const value={
title:"标题",
content:"内容",
id:1
};
...value //将变量value展开
//
// 等价于(不再有大括号)
// title:"标题",
// content:"内容",
// id:1
组件间通信与插槽
React中组件分两种类型,一种是React DOM组件
,一种是React组件
。DOM组件
是指所有React支持的HTML和SVG标签,React组件
表示用户自定义标签。
React组件中的所有的标签属性统称为Props
,并通过Props
来管理。
DOM组件中CSS的写法
CSS中的标签类名属性class在React中要改为className
,以防止与js中的类class
重名。
return(
打开全栈工匠技能包-1小时轻松掌握SSR
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9waWM0LnpoaW1nLmNvbS84MC92Mi00NWMyNWY5NmI2YTQzOWU5N2UzNGJjNjdjNzIyZDFiYl9oZC5qcGc?x-oss-process=image/format,png)
两小时精通jq+bs插件开发
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9waWMzLnpoaW1nLmNvbS84MC92Mi01ZGU5MTQ1ZDI0OWJmZDliNTFiZjMyOTVmMTg2ZGFlZV9oZC5qcGc?x-oss-process=image/format,png)
生产环境下如歌部署Node.js
**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9waWM0LnpoaW1nLmNvbS84MC92Mi01NjcyZjU2ZTg1NTcwMDM3ZTg1ZmJlODI0MDA3MDJiYl9oZC5qcGc?x-oss-process=image/format,png)
网易内部VUE自定义插件库NPM集成
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9waWMzLnpoaW1nLmNvbS84MC92Mi1kN2M3ZWVjOWJiZGVmYjJiMjNjNzExNzgzZWM4MzIwZV9oZC5qcGc?x-oss-process=image/format,png)
谁说前端不用懂安全,XSS跨站脚本的危害
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9waWM0LnpoaW1nLmNvbS84MC92Mi0yNDAwODRhMGFlNzQwNmUzMWI4NjM0NTk3ZTFjOWQwN19oZC5qcGc?x-oss-process=image/format,png)
webpack的loader到底是什么样的?两小时带你写一个自己loader
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9waWMxLnpoaW1nLmNvbS84MC92Mi0xOWQ2YTQ4MTJmZmQzZjZmYzdlYjJmMjJlMjUwZTM2Y19oZC5qcGc?x-oss-process=image/format,png)
S84MC92Mi1kN2M3ZWVjOWJiZGVmYjJiMjNjNzExNzgzZWM4MzIwZV9oZC5qcGc?x-oss-process=image/format,png)
谁说前端不用懂安全,XSS跨站脚本的危害
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9waWM0LnpoaW1nLmNvbS84MC92Mi0yNDAwODRhMGFlNzQwNmUzMWI4NjM0NTk3ZTFjOWQwN19oZC5qcGc?x-oss-process=image/format,png)
webpack的loader到底是什么样的?两小时带你写一个自己loader
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9waWMxLnpoaW1nLmNvbS84MC92Mi0xOWQ2YTQ4MTJmZmQzZjZmYzdlYjJmMjJlMjUwZTM2Y19oZC5qcGc?x-oss-process=image/format,png)