React 18 核心语法
一、使用脚手架搭建项目
使用脚手架搭建一个 React 项目,有全局安装和临时安装两种方式:
全局安装
npm install -g create-react-app // 安装全局脚手架
create-react-app my-app // 创建一个 react 项目
cd my-app // 进入项目
npm start // 启动项目
临时安装(推荐)
使用 npx 来避免全局安装 create-react-app,npx 是 npm 的一个包执行工具,它会临时安装并执行 create-react-app。
npx create-react-app my-app
cd my-app // 进入项目
npm start // 启动项目
二、组件
React 组件有两种创建方式:函数组件和类组件,现在官方主推的是函数式组件。
类组件相比函数组件来说,它的书写更加复杂和冗余,而且还包含了很多更加复杂的生命周期,因此主推函数式组件。
三、JSX
JSX 不是指一个页面,而是一种 JS 的语法扩展,它允许你在 JS 代码中写入类似 HTML 的标记。
JSX 并不是 JS 的一部分,它是被 Babel 这样的 JS 编译器转换成标准的 JS,这样就可以在浏览器中运行了。
JSX 主要用于 React 框架中,因为它提供了一种方便的方式来描述用户界面。在 React 中,你可以使用 JSX 来描述你的组件,这些组件可以是整个页面、页面的某个部分,或者是一个可以复用的 UI 元素。
-
JSX return 后面的小括号()
function App() { return ( <div></div> ); } export default App;JSX return 后面的小括号是书写 JSX 语法时所必须的,这个必须出现在换行的时候;如果是单行写的话,可以不写这个小括号,可以理解为这个小括号把多行的代码变为了一个整体。
为了避免不必要的麻烦,不管是单行还是多行,建议直接写上这个小括号。
-
JSX 的返回值只能有一个根元素
实现 JSX 的返回值只能有一个根元素,可以使用如下方法:
-
在所有内容最外层加一层容器,比如
<div></div>。 -
如果不想加额外容器的话,可以使用 JSX 提供的空标签
<></>,空标签不是一个真实的标签,不能设置 key。 -
如果不想加额外容器还想要设置 key 的话,可以使用 React 自带的 Fragment 组件。
import { Fragment } from "react"; function App() { const list = [ {id: 1, name: '小吴'}, {id: 2, name: '小丽'}, {id: 3, name: '小花'} ] const listContent = list.map(item => ( <Fragment key={item.id}> <li >{item.name}</li> <li>-----------------------</li> </Fragment> )) return ( <div>{listContent}</div> ); } export default App;
-
-
JSX 中使用 HTML 标签(或组件)的时候,不管是单标签还是多标签,都必须要标签闭合
-
JSX 使用 {} 进行插值
插值可以在标签内容和标签属性中使用:
function App() { const divContent = '标签内容' const divTitle = '标签标题' return ( <div title={divTitle}>{divContent}</div> ); } export default App; -
JSX 中可以直接将变量赋值为 HTML 标签内容
function App() { const divContent = <p>标签内容</p> return ( <div>{divContent}</div> ); } export default App; -
事件
function App() { function handleClick(e) { console.log('点击了按钮', e); } return ( <button onClick={handleClick}>按钮</button> ); } export default App;
四、useState 状态处理
使用 React 的 useState 函数来实现数据的响应式,这个函数接受一个状态初始值:
useState(状态初始值)
这个函数调用后,会返回一个数组,这个数组里包括了两个内容:一个是要渲染的数据内容(读),一个是修改状态的函数(写),可以通过数组结构的方式将这两个参数取出。
-
基本数据形式的状态
import { useState } from "react"; function App() { const [content, setContent] = useState('默认内容') function handleClick() { setContent('新内容') } return ( <> <div>{content}</div> <button onClick={handleClick}>按钮</button> </> ); } export default App; -
对象形式的状态
import { useState } from "react"; function App() { const [data, setData] = useState({ title: '默认标题', content: '默认内容' }) function handleClick() { setData({ ...data, content: '新内容' }) } return ( <> <div title={data.title}>{data.content}</div> <button onClick={handleClick}>按钮</button> </> ); } export default App;以上面代码为例,对象形式的状态需要注意的是:
- 不能直接使用
data作为标签属性或内容值,需要精确到data对象中的属性data.xx,不然会报错。 setData()是将整个数据替换掉,因此在修改data中的属性值时,可以使用...data的方式,先将之前的数据引入,然后在后面修改属性值来替换内容。
- 不能直接使用
-
数组形式的状态
import { useState } from "react"; function App() { const [data, setData] = useState([ {id: 1, name: '小猪'}, {id: 2, name: '小鼠'}, {id: 3, name: '小龙'} ]) const listData = data.map(item => ( <li key={item.id}>{item.name}</li> )) function handleClick() { setData([ ...data, {id: 4, name: '小猫'} ]) } return ( <> <ul>{listData}</ul> <button onClick={handleClick}>按钮</button> </> ); } export default App;以上面代码为例,数组形式的状态需要注意的点跟对象形式的状态一样:
- 不能直接使用
data作为标签属性或内容值,不然会报错。 setData()是将整个数据替换掉,因此在修改data内容时需要格外注意。
- 不能直接使用