React类组件基础01-JSX和部分常用API

650 阅读6分钟

写在前面:

1.本文是个人课上学习内容的总结和梳理,主要知识点来自于“开课吧”线上直播课程,以及 React 官方文档。

2.目前尚处于 React 乃至前端入门阶段,因此很多内容理解的不是很透彻,文章更多是用来学习记录而非干货分享。

因此,建议如果需要解决项目问题,还是去看一下其他大佬的文档以及 React 官方文档(一手资料)

JSX 插值语法

为什么使用JSX?

React 认为渲染逻辑本质与其他UI逻辑内在耦合,比如,在UI中需要绑定处理时间、在某些时刻状态发生变化时需要通知到UI,以及需要在UI中展示准备好的数据。

React 不强制要求使用JSX,但是大多数人发现,在JavaScript代码中奖JSX和UI放在一起时,会在视觉上有辅助作用。它还可以使 React 显示更多有用的错误和警告信息。

使用JSX

JSX表达式可以是一个简单的DOM元素对象:

const element = <h1>这是一个DOM元素</h1>

也可以插入JavaScript表达式

  1. 可以插入注释
  2. 可以插入JS表达式

JS表达式:运算后会返回一个值的代码组合。比如,变量、运算式、函数调用

let inner = "这是被插值表达式插入的内容";
let count = 100;

let element = <header className="header div" id="header">
    	<h1>React</h1>
        <div>{inner}</div>
        <div>{count + 1}</div>
    </header>

不同数据类型在插值中的表现

基础类型

  • numberstring:保持原样进行输出
  • booleannullundefinedSymbol:输出时会忽略掉

复合类型

  • object:①如果是react element对象,则正常输出;②普通对象则不能作为内容进行输出

注意事项

  1. JSX 不是字符串

  2. JSX 是一个值,所以 JSX 中,必须有一个顶层(唯一)的父级将JSX包裹起来

    如果父级我们并不希望在DOM中展示出来,可以使用Fragment组件或者空标签<></>

  3. JSX 区分大小写,标签要全部小写,组件的首字母要大写。

  4. JSX 标签必须闭合。

  5. JSX 不是HTML,很多属性在编写时是不一样的。

    • className
    • style
  6. 列表渲染时,必须有 key 值

列表输出

列表循环本质上就是JavaScript中的for循环,常用于处理数组或者对象数据上,可以用列表循环减少很多重复性的代码编写。

let data = {
  a:{
    inner: "列表项1"
  },
  b: {
    inner:"列表项2"
  },
  c: {
    inner:"列表项3"
  }
}

Object.keys(data).map(item=>console.log(data[item]))
let ul = <ul>{Object.keys(data).map(item=><li>{data[item].inner}</li>)}</ul>;

条件输出

通过运算表达式或者函数来进行条件判断,并控制DOM的渲染或者某些状态或者属性的加载。常用的判断语句有:||&&? : function

let is = false;
let is2 = true;
let is3 = false;
let is4 = (nub)=>{
  if(nub < 5){
    return <strong>小于5</strong>
  }
  if(nub < 10){
    return <strong>小于10</strong>
  }
  if(nub < 15){
    return <strong>小于15</strong>
  }
  if(nub < 20){
    return <strong>小于20</strong>
  }
  return <strong>大于等于20</strong>
}
let div = <div>
  <div>{is||<strong>条件不成立时输出</strong>}</div>
  <div>{is2&&<strong>条件成立时输出</strong>}</div>
  <div>{is3?<strong>条件成立时输出</strong>:<strong>条件不成立时输出</strong>}</div>
  <div>{is4(20)}</div>
</div>

组件和状态

React 组件分为两种,一种是类组件,一种是函数组件,在 React 16.7 之前,函数组件只能依赖父级组件进行更新。

类组件:

  1. 类组件必须继承自 Component 类。
  2. 组件名首字母必须大写。
  3. 类组件中必须有一个 render 方法,而且该方法必须有返回值,返回的是当前组件要构建的视图。
  4. 在组件中,有一个 state 属性,该属性中保存的是组件可变的数据,当 state 更新时,会引起组件更新,从而驱动视图更新(数据驱动思想)。

事件:

  1. React 中添加事件类似于 JavaScript 的行间事件。

  2. 事件名是驼峰命名。

  3. 注意事件处理函数的 this 是指向 undefined 的。

    将 this 指向组件实例的方式有两种:

    • 通过箭头语法
    • 通过 .bind 修饰符

更新组件状态

  1. 在组件中要更新状态,需要调用实例的setState方法
  2. setState 本身接收一个参数是该对象的数据,该对象中,是要写入更新后的state。
class App extends Component { // 类组件必须继承自Component类
  state={ // state 属性用来保存该组件的课可变数据
    data: {
      count:1
    }
  }
  handler=()=>{ // 通过箭头语法将this指向该组件
    const {nextCount} = this.state.data; // 声明需要改变的数据
    this.setState({ // 传入需要改变的数据
      data: {
        count: nextCount + 1 // 对数据进行需要的处理
      }
    });
  }
  render(){
    const {count} = this.state.data; // 从 state 里面拿数据需要重新声明一个新变量
    return <div>
      <p>当前数字{count}</p>
      <button onClick={this.handler}>递增</button>
    </div>
  }
}
export default App;

初始化React

ReactElment React.createElement(type,props,...children) 构建视图,返回值是一个用来描述视图的虚拟DOM

  • type 节点类型
  • props 属性 object
  • children 内容或子节点

ReactDOM.render(inner, container[, callback]) 将构建好的视图添加到真实DOM中

  • element 要渲染的内容

  • container 要渲染的内容存放容器

  • callback 渲染后的回调函数

let header = React.createElement("header", {
    className: "header div",
    id: "header"
  }, "hear");

  let element = (<h1>hello</h1>)
  //渲染到真实DOM视图
  ReactDOM.render(
    element,
    document.querySelector("#root"), 
    () => {
      console.log("构建完成")
    }
  );

实例

以数据驱动的思维,实现点击列表,显示下拉栏的功能。先看一下静态页面,显示和因此下拉栏通过css属性进行控制*display*: none/block,如图。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link href="css/index.css" rel="stylesheet" />
</head>
<body>
    <div class="friend-list">
        <dl class="friend-group expanded">
            <dt>家人</dt>
            <dd>爸爸</dd>
            <dd>妈妈</dd>
        </dl>
        <dl class="friend-group">
            <dt>朋友</dt>
            <dd>张三</dd>
            <dd>李四</dd>
            <dd>王五</dd>
        </dl>
        <dl class="friend-group">
            <dt>客户</dt>
            <dd>阿里</dd>
            <dd>腾讯</dd>
            <dd>头条</dd>
        </dl>
    </div>
</body>
</html>
dl {
    margin: 0;
}
.friend-list {
    border: 1px solid #000000;
    width: 200px;
}
.friend-group dt {
    padding: 10px;
    background-color: rgb(64, 158, 255);
    font-weight: bold;
}
.friend-group dd {
    padding: 10px;
    display: none;
}
.friend-group.expanded dd {
    display: block;
}

通过react的实现思路:

  • 数据结构性很强,可以通过结构化的存储数据,并通过列表输出
  • 点击表头的时候,触发事件,事件的回调函数触发 setState 方法,通过修改数据的属性,驱动视图更新
  • 视图通过判断数据的属性,来给className进行判断,从而进行条件输出

index.js 项目入口

import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";

ReactDOM.render(
  <App />,
  document.querySelector("#root")
);

data.js 存储所有数据的数据池

let rootdata = {
  "家人":["爸爸","妈妈"],
  "朋友":["张三","李四","王五"],
  "客户":["阿里","腾讯","头条"]
}; 

export default rootdata;

App.js 组件,唯一的父级组件,负责对data进行处理,通过数组循环将每组的值传递给实例化好的<Dd/>组件

import { Component } from "react";
import rootdata from "./data";
import Dd from "./dd";

class App extends Component {
  render() {
    return <div className="friend-list">
    {Object.keys(rootdata).map((item,index)=>{ 
        return <Dd key={index} title={item} data={rootdata[item]} />
    })}
</div>
  }
}
export default App;

dd.js 子组件,用来渲染每个列表里面的视图,并处理点击事件和回调函数触发条件输出

import { Component } from "react";

class Dd extends Component{
    state = { show: false };
    changeShow = () => {
        const {show} = this.state;
        this.setState({
            show:!show
        })
    };
    render(){
        const { title, data } = this.props;
        const { show } = this.state;
        return (
        <dl className={show?"friend-group expanded":"friend-group"}>
            <dt onClick={this.changeShow}> {title} </dt>
            {data.map((item,index)=> <dd key={index}> {item} </dd>)}
            //react特性:js表达式也可以渲染成UI
        </dl>
        )
    }
};

export default Dd;

最终实现的效果如下图: