React基础整理

React基础

React介绍

The library for web and native user interfaces

用于构建Web和原生交互界面的库

React 是一个用于构建用户界面的 JavaScript 库,由 Meta(原 Facebook)维护,核心目标是 “让构建交互式 UI 变得简单”。官网强调:React 不是框架,而是专注于 “视图层” 的库,可与其他工具(如路由、状态管理库)组合,构建完整应用。

写笔记的时候我就在想 ,应该先写JSX语法还是React组件,因为官网的教程是先介绍了组件相关的概念再介绍JSX的语法,因为JSX和React是相互独立的东西,JSX是一种语法扩展,而React则是一个JavaScript的库,但是在 React 中,渲染逻辑和标签共同存在于同一个地方——组件,React的核心就是是用组件构建 UI,但组件的 视图部分 全靠 JSX 描述(用JS写HTML 标签),所以我觉得先介绍JSX语法,再写组件相关的概念。

JSX语法

JSX: 将标签引入 JavaScript

JSX 是 JavaScript 语法扩展,可以让你在 JavaScript 文件中书写类似 HTML 的标签。

function MyButton() {
  return (
    <button>
      我是一个按钮
    </button>
  );
}

使用 JSX 编写标签的限制

JSX 比 HTML 更加严格。你必须闭合标签,如 <br />。还有编写组件时不能返回多个 JSX 标签。你必须将它们包裹到一个共享的父级中,比如 <div>...</div> 或使用空的 <>...</> 包裹(只能返回一个根元素)。

function AboutPage() {
  return (
    <>
      <h1>关于</h1>
      <p>你好。<br />最近怎么样?</p>
    </>
  );
}

使用驼峰式命名法给大部分属性命名

JSX 最终会被转化为 JavaScript,而 JSX 中的属性也会变成 JavaScript 对象中的键值对。在你自己的组件中,经常会遇到需要用变量的方式读取这些属性的时候。但 JavaScript 对变量的命名有限制。例如,变量名称不能包含 - 符号或者像 class 这样的保留字。

在 React 中,可以使用 className 来指定一个 CSS 的 class。它与 HTML 的 class 属性的工作方式相同。

<img className="avatar" />

官网提供了所有的React DOM元素属性,如果写错了也不用担心,React会在浏览器控制台打印可能的更正信息提示。

显示动态数据

在一些场景下我们需要在标签中添加一些 JavaScript 逻辑或者引用动态的属性。这种情况下,可以在 JSX 的大括号内来编写 JavaScript。

  • 我们可以在标签中用大括号来加载动态的数据,如 {user.name}会获取 user.name变量显示在 h1 标签中。
return (
  <h1>
    {user.name}
  </h1>
);
  • 也可以使用大括号代替引号来加载动态的属性,如 src={user.imageUrl} 会获取user.imageUrl 变量,然后将该值作为 src 属性传递:
return (
  <img
    className="avatar"
    src={user.imageUrl}
  />
);

也可以把更为复杂的表达式放入 JSX 的大括号内,例如字符串拼接、三元表达式、对象等。

const user = {
  name: 'Hedy Lamarr',
  imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',
  imageSize: 90,
};

return (
  <>
    <h1>{user.name}</h1>
    <img
      className="avatar"
      src={user.imageUrl}
      alt={'Photo of ' + user.name}
      style={{
        width: user.imageSize,
        height: user.imageSize
      }}
    />
  </> 
);

条件渲染

React 没有特殊的语法来编写条件语句,因此你使用的就是普通的 JavaScript 代码。例如使用 if 语句根据条件引入 :

let content;
if (isLoggedIn) {
  content = <AdminPanel />;
} else {
  content = <LoginForm />;
}
return (
  <div>
    {content}
  </div>
);

也可以使用三元表达式:

<div>
  {isLoggedIn ? (
    <AdminPanel />
  ) : (
    <LoginForm />
  )}
</div>

逻辑 && 语法也是没问题的:

<div>
  {isLoggedIn && <AdminPanel />}
</div>

渲染列表

我们可以依赖 JavaScript 的特性,例如 for 循环 和 array 的 map() 函数 来渲染组件列表(jsx会自动展开标签数组):

const products = [
  { title: 'Cabbage', id: 1 },
  { title: 'Garlic', id: 2 },
  { title: 'Apple', id: 3 },
];

const listItems = products.map(product =>
  <li key={product.id}>
    {product.title}
  </li>
);

return (
  <ul>{listItems}</ul>
);

/*
<ul>{listItems}</ul>
解析后会变成
<ul>
	<li>...</li>
	<li>...</li>
	<li>...</li>
</ul>
*/

React组件

组件是什么?

首先我们要知道什么是组件,在 React 中,组件是「独立、可复用、可组合的 UI 单元」 —— 我们把它理解成「搭建页面的积木」就特别好懂:一块积木(组件)有自己的形状(UI 结构)和特性(逻辑),可以单独用,也可以和其他积木拼在一起,组成复杂的页面(比如头部、列表、按钮,甚至整个页面,都能是一个组件)。

如何定义组件?

函数组件

函数组件是用JavaScript 函数定义的组件,也是 React 16.8 推出 Hooks 后最核心的组件形式,它让函数组件拥有了状态管理和生命周期能力,代码更简洁、轻量化。

// 这就是一个简单的函数组件
export default function HelloWorld() {
  return <h1>Hello React 函数组件</h1>
}

构建组件的方法主要有以下几步:

  1. 定义函数,定义函数大家都会的吧,使用函数声明或者箭头函数定义都可以(函数名也就是组件名首字母必须大写)。
  2. 在函数体中编写组件逻辑并返回标签(只能返回一个根元素,有换行则需要用小括号包裹起来)。
  3. 导出组件(可以使用 默认导出 或 具名导出)。
类组件

类组件是 React 16.8 之前的主流写法,Hooks 推出后,函数组件 + Hooks 已成为首选;类组件无需深入学习,但需了解基础结构和核心概念,用于理解历史代码和对比 Hooks(注意:这篇笔记只有部分知识点写了类组件写法)。

class HelloWorld extends React.Component {
  render() {
    return <h1>Hello React 类组件</h1>;
  }
}

组件 props

React 组件使用 props 来互相通信。每个父组件都可以提供 props 给它的子组件,从而将一些信息传递给它。

  1. props传递给子组件

    我们可以在使用组件时,通过一些自定义属性,向组件内部传递信息

    export default function Page() {
      return (
      	<HelloWorld info={{ type: '函数' }} />
      )
    
  2. 在子组件中读取 props

    // 函数组件
    export default function HelloWorld (props) {
      return <h1>Hello React {props.info.type}组件</h1>
    }
    
    // 也可以使用解构获取属性
    export default function HelloWorld ({ info }) {
      return <h1>Hello React {info.type}组件</h1>
    }
    
    // 类组件
    class HelloWorld extends React.Component {
      const { info } = this.props
      render() {
        return <h1>Hello React {info.type}组件</h1>;
      }
    }
    
  3. props 默认值

    如果你想在没有指定值的情况下给函数组件 prop 一个默认值,可以通过在参数后面写 = 默认值 来进行解构。

    export default function HelloWorld ({ info = { type: '函数' } }) {
      return <h1>Hello React {info.type}组件</h1>
    }
    

    类组件使用静态属性 defaultProps 来设置 prop 的默认值

    class HelloWorld extends React.Component {
      static defaultProps = {
        info: {
          type: '类'
        }
      }
      const { info } = this.props
      render() {
        return <h1>Hello React {info.type}组件</h1>;
      }
    }
    

注意:

  1. props 对象存储的值是只读的,不能再组件内部被修改。
  2. props数据源中的数据被修改后,组件中接收到的 props数据会被同步更新。
  3. HelloWorld.defaultProps 这种写法依然有效,但 React 官方已明确「不推荐在函数组件中使用」,更建议用「参数解构默认值」替代;仅在类组件中,defaultProps 仍可作为兼容写法(但也非首选)。

组件响应事件

使用 React 可以在 JSX 中添加 事件处理函数。其中事件处理函数为自定义函数,它将在响应交互(如点击、悬停、表单输入框获得焦点等)时触发。

绑定事件处理函数
  1. 在组件内部声明一个函数
  2. 实现函数内部的逻辑
  3. 绑定事件函数

这里以按钮组件为例:

export default function Button() {
  // 事件处理函数
  function handleClick() {
    alert('你点击了我!');
  }

  return (
    // 绑定点击事件函数
    <button onClick={handleClick}>
      点我
    </button>
  );
}

组件状态 State

组件通常需要根据交互更改屏幕上显示的内容。输入表单应该更新输入字段,单击轮播图上的“下一个”应该更改显示的图片,单击“购买”应该将商品放入购物车。

添加state变量
import { useState } from 'react';

const [state, setState] = useState(initialState)

useState 返回一个由两个值组成的数组:

  1. 当前的 state。在首次渲染时,它将与你传递的 initialState 相匹配。
  2. set 函数,它可以让你将 state 更新为不同的值并触发重新渲染。

这里还是用一个按钮组件来展示state的使用:

import { useState } from 'react';


export default function Button() {
  const [index, setIndex] = useState(0)
  // 事件处理函数
  function handleClick() {
    alert('你点击了我!');
    setIndex(index + 1)
  }
	
  return (
    // 绑定点击事件函数
    <>
    	<p>按钮被点击了{index}次</p>
    	<button onClick={handleClick}>
      	点我
    	</button>
    </>
  );
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值