react的特点
-
组件化: React鼓励使用组件化的方式来构建界面,每个组件可以封装自己的逻辑和样式,使得代码更加模块化和可重用。
-
虚拟DOM: React使用虚拟DOM来提高性能。当组件的状态发生变化时,React会首先在虚拟DOM上进行计算,然后通过高效的算法来决定如何更新实际的DOM,这样可以减少浏览器的重绘和重排操作。就是先通过js控制页面,减少重复页面渲染
-
状态管理: React组件可以拥有自己的状态(state),当状态发生变化时,组件会自动重新渲染。这种状态管理机制使得界面的交互和动态变化更加容易实现。
-
JSX: React使用JSX语法扩展,它允许在JavaScript代码中直接写类似HTML的标记,但JSX实际上会被编译成JavaScript对象。JSX使得开发者能够以声明式的方式来描述UI组件的结构。reactDOM.render(不要写引号的html界面,要绑定的组件id)
-
生命周期: React组件有明确的生命周期,包括挂载(mounting)、更新(updating)、卸载(unmounting)等阶段,开发者可以在不同的生命周期阶段执行特定的操作。
-
可维护性: 由于React的组件化特性,使得大型应用的维护和扩展变得更加容易。
React组件
函数名作为组件导入
在react中,允许这种写法
function Profile() {
return (
<img
src="https://i.imgur.com/MK3eW3As.jpg"
alt="Katherine Johnson"
/>
);
}
export default function Gallery() {
return (
<section>
<h1>了不起的科学家</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}
return的数据会直接写入到html中,而函数名可以作为标签组件传入到返回的数据中
-
<section>
是小写的,所以 React 知道我们指的是 HTML 标签。 -
<Profile />
以大写P
开头,所以 React 知道我们想要使用名为Profile
的组件。
注意事项
-
不要在组件中声明组件,不能嵌套执行
-
子组件需要使用父组件的数据时,你需要 通过 props 的形式进行传递,而不是嵌套定义
-
在export default function的返回值中, 不能在没有原生html的标签下并排写两个组件标签 这种情况会报错
export default function App() { return ( <Gallery /> <br></br> <Profile /> ); } // 正确写法: export default function App() { return ( <div> <Gallery /> <br></br> <Profile /> </div> ); }
根组件
实际上就是存放组件的js文件
-
所有组件目前都定义在 根组件
App.js
文件中。具体还需根据项目配置决定,有些根组件可能会声明在其他文件中。
在实际使用时,根组件通过jsX入口文件写入到html的指定id处
App.js: 【根组件文件】
import React from 'react';
function App() {
return (
<div>
<h1>Hello, World!</h1>
</div>
);
}
export default App;
index.js (入口文件):
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'; // 引入App组件
ReactDOM.render(
<React.StrictMode>
<App /> // 将App组件渲染到页面上
</React.StrictMode>,
document.getElementById('root') // 找到HTML中的root元素
);
index.html (HTML文件):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React App</title>
</head>
<body>
<div id="root"></div> <!-- React应用的挂载点 -->
<!-- 你的React应用将被渲染到这个div中 -->
</body>
</html>
组件的导入导出
可以根据以下三个步骤对组件进行拆分:
在组件内部,函数可以作为标签导入 在组件之间,组件通过import传入后作为标签导入
Gallery.js文件
-
定义了
Profile
组件,该组件仅在该文件内使用,没有被导出。 -
使用 默认导出 [ export default ] 的方式,将
Gallery
组件导出
function Profile() {
return (
<img
src="https://i.imgur.com/QIrZWGIs.jpg"
alt="Alan L. Hart"
/>
);
}
export default function Gallery() {
return (
<section>
<h1>了不起的科学家们</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}
根组件App.js
-
使用 默认导入 [ import Gallery from './Gallery.js'; ] 的方式,从
Gallery.js
中导入Gallery
组件。-
不论是 ./Gallery.js 还是 ./Gallery 都能被识别
-
-
使用 默认导出 [ export default ] 的方式,将根组件
App
导出。
import Gallery from './Gallery.js';
export default function App() {
return (
<Gallery />
);
}
跟Vue很像啊
默认和具名
两种不同的导入导出方式, 区别是引入时是否带 { } 一个文件里有且仅有一个 默认 导出,但是可以有任意多个 具名 导出。
-
这句话意思是一个js只能有一个export default function Button(), 但是可以有多个export function Button1()
-
其中组件引用时, 可以获取到整个的 Button, 也可以只获取其中一个组件 Button1
语法 | 导出语句 | 导入语句 |
---|---|---|
默认 | export default function Button() {} | import Button from './Button.js'; |
具名 | export function Button1() {} | import { Button1 } from './Button.js'; |
复合导入
在导入的组件中,部分导入其内部的组件
Gallery.js文件
-
使用 具名导出 的方式,将
Profile
组件导出,并取名为Profile
。 -
使用 默认导出 的方式,将
Gallery
组件导出。
export function Profile() {
return (
<h1>hhh</h1>
);
}
export default function Gallery() {
return (
<section>
<h1>了不起的科学家们</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}
App.js文件
-
使用 具名导入 的方式,从
Gallery.js
中导入Profile
组件,并取名为Profile
。 -
使用 默认导入 的方式,从
Gallery.js
中导入Gallery
组件。 -
使用 默认导出 的方式,将根组件
App
导出。
import Gallery from './Gallery.js';
import { Profile } from './Gallery.js';
export default function App() {
return (
<div>
<Gallery />
<br></br>
<Profile />
</div>
);
}
可以发现成功输出了组件和组件内部的具名组件
常见的导出方式
-
使用
export function
进行具名导出:
export function MyComponent() { return <div>这是一个组件</div>; }
这样导出的组件可以在其他文件中通过名称MyComponent
来导入。
-
使用
export default
进行默认导出:
export default function MyComponent() { return <div>这是一个组件</div>; }
使用export default
时,导出的组件在导入时不需要指定名称,但每个文件只能有一个默认导出。
-
使用
export
关键字导出类组件:
export class MyComponent extends React.Component { render() { return <div>这是一个组件</div>; } }
类组件也可以通过这种方式进行具名导出。
-
使用
export
关键字导出变量或常量:
const MyComponent = () => { return <div>这是一个组件</div>; }; export { MyComponent };
这种方式可以导出变量或常量,并且在导入时需要使用花括号{}
指定名称。
-
使用
export
进行批量具名导出:
export { MyComponent, AnotherComponent };
这种方式可以同时导出多个组件或变量。
-
使用
as
关键字重命名导出:
export { MyComponent as ComponentName };
JSX: 将标签引入 JavaScript
一种JavaScript的扩展,在react中使用jsX来描述用户界面
你可以把react理解为用JavaScript写html
在 React 中,渲染逻辑和标签共同存在于同一个地方——组件
JSX 语法更加严格并且相比 HTML 有更多的规则
JSX语法规则
-
只能返回一个根元素
-
如果想要在一个组件中包含多个元素,需要用一个父标签把它们包裹起来。
-
该父标签可以是 <> </> 就是不带任何概念,这个空标签被称作 Fragment。React Fragment 允许你将子元素分组,而不会在 HTML 结构中添加额外节点。
-
原因: JSX 虽然看起来很像 HTML,但在底层其实被转化为了 JavaScript 对象,你不能在一个函数中返回多个对象,除非用一个数组把他们包装起来。这就是为什么多个 JSX 标签必须要用一个父元素或者 Fragment 来包裹。
-
-
标签必须正确闭合
-
自闭合标签, 如 <img>, <br> 等必须写为 <img/> 和 <br/>
-
-
使用驼峰式命名法给大部分属性命名
-
JSX 最终会被转化为 JavaScript,而 JSX 中的属性也会变成 JavaScript 对象中的键值对。在你自己的组件中,经常会遇到需要用变量的方式读取这些属性的时候。但 JavaScript 对变量的命名有限制。例如,变量名称不能包含
-
符号或者像class
这样的保留字。 -
用驼峰命名法代替哪些 - 链接的属性, 如用
strokeWidth
代替stroke-width
-
class 属性需要改为 className !!!!
-
jsX转化器
一个网站, 把html转换为JsX
在Jsx中使用JavaScript
和Vue类似, 通过 { } 大括号传递js变量
export default function Avatar() {
const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
const description = 'Gregorio Y. Zara';
return (
<img
className="avatar"
src={avatar}
alt={description}
/>
);
}
和Vue不同的是大括号内的任何 JavaScript 表达式都能正常运行
用大括号的场景
在 JSX 中,只能在以下两种场景中使用大括号:
-
用作 JSX 标签内的文本:
<h1>{name}'s To Do List</h1>
是有效的,但是<{tag}>Gregorio Y. Zara's To Do List</{tag}>
无效。 -
用作紧跟在
=
符号后的 属性:src={avatar}
会读取avatar
变量,但是src="{avatar}"
只会传一个字符串{avatar}
。
传递对象
除了字符串、数字和其它 JavaScript 表达式,你还可以在 JSX 中传递对象。对象也用大括号表示 在 JSX 中看到 {{
和 }}
时,就知道它只不过是包在大括号里的一个对象罢了
例子中的JSX中的内联样式实际上是在style中传入了一个js对象
export default function TodoList() {
return (
<ul style={{
backgroundColor: 'black',
color: 'pink'
}}>
<li>Improve the videophone</li>
<li>Prepare aeronautics lectures</li>
<li>Work on the alcohol-fuelled engine</li>
</ul>
);
}
传递对象参数
和Vue类似的操作,但是Vue是在html中, 而react是在js中
const person = {
name: 'Gregorio Y. Zara',
theme: {
backgroundColor: 'black',
color: 'pink'
}
};
export default function TodoList() {
return (
<div style={person.theme}>
<h1>{person.name}'s Todos</h1>
<img
className="avatar"
src="https://i.imgur.com/7vQD0fPs.jpg"
alt="Gregorio Y. Zara"
/>
<ul>
<li>Improve the videophone</li>
<li>Prepare aeronautics lectures</li>
<li>Work on the alcohol-fuelled engine</li>
</ul>
</div>
);
}
多个对象传递
-
传入多个变量时, 不要使用多个{ } 进行传入, 而是使用一个大的 { } 内嵌多个变量
const baseUrl = 'https://i.imgur.com/';
const person = {
name: 'Gregorio Y. Zara',
imageId: '7vQD0fP',
imageSize: 's',
theme: {
backgroundColor: 'black',
color: 'pink'
}
};
export default function TodoList() {
return (
<div style={person.theme}>
<h1>{person.name}'s Todos</h1>
<img
className="avatar"
src={baseUrl + person.imageId + person.imageSize + '.jpg'}
// 错误写法: src="{baseUrl}+{person.imageId}+{person.imageSize}.jpg"
alt={person.name}
/>
<ul>
<li>Improve the videophone</li>
<li>Prepare aeronautics lectures</li>
<li>Work on the alcohol-fuelled engine</li>
</ul>
</div>
);
}
注意事项
-
JSX and React 是相互独立的 东西。但它们经常一起使用,但你 可以 单独使用它们中的任意一个,JSX 是一种语法扩展,而 React 则是一个 JavaScript 的库。
-
JsX中的内联样式一样要使用驼峰命名法, 如 background-color 写为 backgroundColor