React 18 核心语法

255 阅读4分钟

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 内容时需要格外注意。