React 组件学习(函数组件、 类组件)

目录

1. React 组件介绍

2. 函数组件

1)什么是函数组件?

2)定义函数组件

3)使用组件

总结:

3. 类组件-复习 class 语法 

1.掌握 class 定义类,定义属性,定义函数

 2.掌握 extends 继承父类

4. 类组件-基本使用步骤

1.什么是类组件?

2.定义类组件

3.使用类组件

总结:

5. 类组件-组件抽离

 6. 类组件-无状态组件和有状态组件和

1.无状态组件 

2.有状态组件 

3.它们的区别 

4.如何去选择 

总结:

7. 类组件-定义状态

大致步骤:

具体代码:

8. 类组件-绑定事件 

大致步骤:

具体代码:

总结:

9. 类组件-发现 this 问题 

1.发现this是undefined

 2.演示处理函数调用对 this 的影响

 3.问题原因

总结:

10. 类组件-处理 this 问题 

 1.通过绑定箭头函数解决 this 问题

 2.通过 bind 解决 this 问题

 3.通过声明箭头函数解决 this 问题

总结:

11. 类组件-setState 使用 

1.通过setState的来修改数据更新视图

2.修改数组和修改对象的正确姿势

总结:

12. 类组件-受控组件 

13. 类组件-非受控组件

1. React 组件介绍

了解 React 组件作用,和创建组件的方式 

官方解释:

  • 组件允许你将 UI 拆分为独立可复用的代码片段,并对每个片段进行独立构思。

前端开发:

  • 将页面按照界面功能进行拆分,每一块界面都拥有自己的独立逻辑,这样可以提高项目代码的可维护性

React 创建组件:

  1. 使用函数 function
  2. 使用类 class

2. 函数组件

目标:掌握在 React 中使用函数创建组件,使用组件。 

大致步骤:

  • 什么是函数组件
  • 定义函数组件
  • 使用函数组件

具体内容:

1)什么是函数组件?

  • 使用 JS 函数(普通,箭头)创建的组件

2)定义函数组件

  • 语法约定
    • 函数名称首字母必需大写,React 据此来区分组件和 HTML 元素
    • 函数必须有返回值,表示该组件的 UI 结构,如果不渲染任何内容可返回null
// 普通函数
function Header() {
  return <div>头部组件</div>;
}
// 箭头函数
const Footer = () => {
  return <div>底部组件</div>;
};
// 不渲染内容
const Loading = () => {
  const loading = false;
  return loading ? <div>正在加载...</div> : null;
};

3)使用组件

  • 函数的名称就是组件名称,使用组件就是把组件名称当标签使用即可。
import ReactDom from 'react-dom';

// 普通函数
function Header() {
  return <div>头部组件</div>;
}

// 箭头函数
const Footer = () => {
  return <div>底部组件</div>;
};

// 加载组件,不渲染内容
const Loading = () => {
  const loading = false;
  return loading ? <div>正在加载...</div> : null;
};

// 根组件
const App = () => {
  return (
    <>
      <Header />
      <Loading />
      <Footer />
    </>
  );
};

ReactDom.render(<App />, document.getElementById('root'));

总结:

  • 创建函数组件,首字母大写,需要返回值,不渲染就返回 null
  • 使用函数组件,组件名称当作标签使用即可

3. 类组件-复习 class 语法 

 回顾 class 语法定义类属性和函数,回顾 extends 语法继承父类。

大致步骤:

  • 掌握 class 定义类,定义属性,定义函数。
  • 掌握 extends 继承父类。

具体内容:

1.掌握 class 定义类,定义属性,定义函数

// 动物
class Animal {
  address = '地球';
  eat() {
    console.log('吃');
  }
}

 2.掌握 extends 继承父类

// 猫
class Cat extends Animal {
  run() {
    console.log('跑');
  }
}

const cat = new Cat();
cat.run(); // 跑
cat.eat(); // 吃
console.log(cat.address); // 地球

 总结: class创建类,extends继承类,可以使用父类的属性和函数。

4. 类组件-基本使用步骤

 掌握 React 的类组件写法

大致步骤

  • 什么是类组件
  • 定义类组件
  • 使用类组件

具体内容

1.什么是类组件?

  • 使用class语法创建的组件就是类组件

2.定义类组件

  • 约定:类名首字母必需大写
  • 约定:必须继承React.Component父类
  • 约定:必需有render函数,返回 UI 结构,无渲染可返回 null
import { Component } from 'react';

class Header extends Component {
  render() {
    return <div>头部组件</div>;
  }
}

3.使用类组件

  • 类名称就是组件名称,使用组件就是把组件名称当标签使用即可。
import { Component } from 'react';
import ReactDom from 'react-dom';

// 头部
class Header extends Component {
  render() {
    return <div>头部组件</div>;
  }
}

// 根组件
class App extends Component {
  render() {
    return (
      <>
        <Header />
      </>
    );
  }
}

ReactDom.render(<App />, document.getElementById('root'));

总结:

  • 使用class定义类,使用extends继承React.Component完成类组件定义
  • 类名首字母大写,必须有render函数返回 UI 结构,无渲染可返回null
  • 使用的时候把类名当作标签使用即可

5. 类组件-组件抽离

 理解组件抽离目的,掌握抽离组件方式。

大致步骤:

1.思考,如果所有组件写在一个文件好维护吗?

  • 不好维护,代码写在一起。

2.抽离组件 

  • 定义一个js或者jsx文件定义组件默认导出
  • 使用组件导入即可,当作标签使用。

具体操作: 

 1.新建 src/components/Header.jsx 类组件,新建 src/components/Footer.jsx 函数组件

import { Component } from 'react';
class Header extends Component {
  render() {
    return <div>头部组件</div>;
  }
}
export default Header;
const Footer = () => {
  return <div>头部组件</div>;
};
export default Footer;

2.新建 src/App.jsx 组件, 导入Header Footer组件使用。

import { Component } from 'react';
import Header from './components/Header.jsx';
import Footer from './components/Footer.jsx';
class App extends Component {
  render() {
    return (
      <>
        <Header />
        内容
        <Footer />
      </>
    );
  }
}

3.index.js 使用 App 根组件

import ReactDom from 'react-dom';
import App from './App.jsx';
ReactDom.render(<App />, document.getElementById('root'));

总结:

  • 建议定义组件使用单独的文件
  • 思考,何时使用类组件,何时使用函数组件?

 6. 类组件-无状态组件和有状态组件和

理解无状态组件和有状态组件概念

大致步骤:

  • 理解什么是无状态组件
  • 理解什么是有状态组件
  • 它们的区别是什么,如何选择使用

具体内容:

1.无状态组件 

  • 组件本身不定义状态,没有组件生命周期,只负责 UI 渲染。
  • React16.8之前的函数组件都是无状态组件,Hooks 出现后函数组件也可以有状态。

2.有状态组件 

  • 组件本身有独立数据,拥有组件生命周期,存在交互行为。
  • class 组件可以定义组件自己的状态,拥有组件生命周期,它是有状态组件。

3.它们的区别 

  • 无状态组件由于没有维护状态只做渲染,性能较好。有状态组件提供数据和生命周期,能力更强。

4.如何去选择 

  • React16.8之前,组件不需要维护数据只渲染就使用函数组件,有数据和交互使用类组件。你需要去判断,有心智负担。
  • React16.8之后,Hooks出现给函数提供状态,建议使用函数组件即可。

总结:

  • 组件本身没有状态就是无状态组件,组件本身提供状态就是有状态组件。
  • 16.8 之前,无状态组件使用函数组件,有状态组件使用类组件。16.8 之后,统一可使用函数组件。
  • React 没有说完全取代类组件,老项目中还是类组件居多,我们有必要学习下它的具体用法。

7. 类组件-定义状态

掌握类组件中状态的定义与使用 

大致步骤:

  • 定义state属性定义组件状态,属于组件自己的数据,它的值是个对象。
  • 使用state的时候通过this去访问即可,例如:this.state.xxx
  • 数据发生变化,驱动视图更新。

具体代码:

import { Component } from 'react';

class App extends Component {
  // 状态
  state = {
    title: '数码产品',
    list: ['电脑', '手机', '相机'],
  };
  render() {
    return (
      <>
        <h3>{this.state.title}</h3>
        <ul>
          {this.state.list.map((item) => {
            return <li key={item}>{item}</li>;
          })}
        </ul>
      </>
    );
  }
}
export default App;

总结:

  • 定义state属性,值是对象存储数据,this.state.xxx使用数据,数据驱动试题更新。

8. 类组件-绑定事件 

掌握类组件中绑定事件的方式,和获取事件对象的方式。 

大致步骤:

  • 在类中声明事件处理函数,在标签上使用on+事件名称={处理函数}的方式绑定事件,事件名称需要遵循大驼峰规则。
  • 处理函数默认的参数就是事件对象,可以使用事件对象处理默认行为和事件冒泡。

具体代码:

import { Component } from 'react';

class App extends Component {
  // 状态
  state = {
    count: 0,
  };
  // 事件处理函数
  handleClick(e) {
    // 默认行为
    e.preventDefault();
    // 事件冒泡
    e.stopPropagation();
    console.log('handleClick');
  }
  handleMouseEnter() {
    console.log('handleMouseEnter');
  }
  render() {
    return (
      <>
        <div onMouseEnter={this.handleMouseEnter}>
          计数器:{this.state.count}
        </div>
        <div>
          <a href="http://www.itcast.cn" onClick={this.handleClick}>
            按钮
          </a>
        </div>
      </>
    );
  }
}
export default App;

总结:

  • 绑定事件的方式和原生的方式一致,使用 on+事件名称={处理函数} 方式绑定
  • 事件名称使用大驼峰规则,例如:onClick onMouseEnter , 处理函数默认传参为事件对象。

9. 类组件-发现 this 问题 

发现事件处理函数中 this 获取不到问题和原因 

大致步骤:

  • 在事件处理函数中打印 this.state.count 发现报错,this 是个undefined
  • 演示函数调用对 this 指向的影响,得出函数谁调 this 就执行谁。
  • 找出原因:处理函数不是通过组件去调用的,导致出现 this 不是组件问题。

具体代码:

1.发现thisundefined

import { Component } from 'react';

class App extends Component {
  // 状态
  state = {
    count: 0,
  };
  // 事件处理函数
  handleClick(e) {
    console.log(e);
    // Uncaught TypeError: Cannot read properties of undefined (reading 'state')
    console.log(this.state.count);
  }
  render() {
    return (
      <>
        <div>计数器:{this.state.count}</div>
        <div>
          <button onClick={this.handleClick}>按钮</button>
        </div>
      </>
    );
  }
}
export default App;

 2.演示处理函数调用对 this 的影响

const obj = {
  name: 'tom',
  say() {
    console.log(this);
  },
};
obj.say(); // 打印:{name: 'tom', say: function}
const say = obj.say;
say(); // 打印:window对象  严格模式

 3.问题原因

  • 类组件声明的处理函数,赋值给 on+事件名称 属性,调用的时候不是通过组件调用的。

总结:

  • 这个 this 问题是 JS 原生就存在,要解决这个问题需要通过 JS 的方式。

10. 类组件-处理 this 问题 

 掌握通过 绑定箭头函数 bind 声明箭头函数 三种方式解决 this 问题

大致步骤:

  • 通过绑定箭头函数解决 this 问题
  • 通过 bind 解决 this 问题
  • 通过声明箭头函数解决 this 问题

具体内容:

 1.通过绑定箭头函数解决 this 问题

import { Component } from "react";

class App extends Component {
  // 状态
  state = {
    count: 0,
  };
  // 事件处理函数
  handleClick(e) {
    console.log(e)
    console.log(this.state.count)
  }
  render() {
    return (
      <>
        <div>计数器:{this.state.count}</div>
        <div>
+          <button onClick={(e)=>this.handleClick(e)}>按钮</button>
        </div>
      </>
    );
  }
}
export default App;

 2.通过 bind 解决 this 问题

import { Component } from "react";

class App extends Component {
  // 状态
  state = {
    count: 0,
  };
  // 事件处理函数
  handleClick(e) {
    console.log(e)
    console.log(this.state.count)
  }
  render() {
    return (
      <>
        <div>计数器:{this.state.count}</div>
        <div>
+          <button onClick={this.handleClick.bind(this)}>按钮</button>
        </div>
      </>
    );
  }
}
export default App;

 3.通过声明箭头函数解决 this 问题

import { Component } from "react";

class App extends Component {
  // 状态
  state = {
    count: 0,
  };
  // 事件处理函数
+  handleClick = (e) => {
    console.log(e)
    console.log(this.state.count)
  }
  render() {
    return (
      <>
        <div>计数器:{this.state.count}</div>
        <div>
          <button onClick={this.handleClick}>按钮</button>
        </div>
      </>
    );
  }
}
export default App;

总结:

  • 三种方式任何一种都可行,建议使用第三种,定义类中的事件处理函数统一使用箭头函数

11. 类组件-setState 使用 

 掌握使用 setState 函数修改组件状态

大致步骤:

  • React 类组件提供一个函数setState({需修改数据}),可以更新数据和视图。
  • 直接修改 state 中的数据是不会更新视图,演示简单数据,数组,对象的正确修改方式。

具体代码: 

1.通过setState的来修改数据更新视图

import { Component } from 'react';

class App extends Component {
  state = {
    count: 0,
  };
  handleClick = () => {
    // 修改数据
    this.setState({
      // key是要修改的数据名称,value是对应的新值
      count: this.state.count + 1,
    });
  };
  render() {
    return (
      <>
        <div>计数器:{this.state.count}</div>
        <div>
          <button onClick={this.handleClick}>按钮</button>
        </div>
      </>
    );
  }
}
export default App;

2.修改数组和修改对象的正确姿势

import { Component } from 'react';

class App extends Component {
  state = {
    count: 0,
    user: {
      name: 'jack',
      age: 18,
    },
    list: ['电脑', '手机'],
  };
  handleClick = () => {
    // 修改数据
    this.setState({
      // key是要修改的数据名称,value是对应的新值
      count: this.state.count + 1,
    });
  };
  updateList = () => {
    // 修改列表
    this.setState({
      list: [...this.state.list, '相机'],
    });
  };
  updateUser = () => {
    // 修改对象
    this.setState({
      user: {
        ...this.state.user,
        name: 'tony',
      },
    });
  };
  render() {
    return (
      <>
        <div>计数器:{this.state.count}</div>
        <div>
          <button onClick={this.handleClick}>按钮</button>
        </div>
        <hr />
        <div>商品:{this.state.list.join(',')}</div>
        <button onClick={this.updateList}>改数组</button>
        <hr />
        <div>
          姓名:{this.state.user.name},年龄:{this.state.user.age}
        </div>
        <button onClick={this.updateUser}>改对象</button>
      </>
    );
  }
}
export default App;

总结:

  • 修改状态数据,使用setState修改可更新视图。

12. 类组件-受控组件 

理解受控组件概念,掌握动态绑定表单元素。 

大致步骤:

  • 什么是受控组件?
  • 如何绑定表单元素

具体内容:

1.什么是受控组件

  • 表单元素的值被 React 中state控制,这个表单元素就是受控组件。

 2.如何绑定表单元素,如:input:text input:checkbox

import { Component } from 'react';

class App extends Component {
  state = {
    mobile: '13811112222',
    isAgree: true,
  };

  changeMobile = (e) => {
    this.setState({
      mobile: e.target.value,
    });
  };

  changeAgree = (e) => {
    this.setState({
      isAgree: e.target.checked,
    });
  };

  render() {
    return (
      <>
        <div>
          <input
            value={this.state.mobile}
            onChange={this.changeMobile}
            type="text"
            placeholder="请输入手机号"
          />
        </div>
        <div>
          <input
            checked={this.state.isAgree}
            onChange={this.changeAgree}
            type="checkbox"
          />
          同意用户协议和隐私条款
        </div>
      </>
    );
  }
}
export default App;

总结:

  • 使用state的数据赋值给表单原生,通过onChange监听值改变修改 state 数据,完成表单元素的绑定。
  • 这种表单元素称为受控组件。

13. 类组件-非受控组件

 理解非受控组件概念,掌握通过 ref 获取元素。

大致步骤:

  • 什么是非受控组件?
  • 通过 ref 获取表单元素获取非受控组件的值

具体内容:

1.什么是非受控组件?

  • 没有通过 state 控制的表单元素,它自己控制自身的值,就是非受控组件

2.通过 ref 获取表单元素获取非受控组件的值

import { Component, createRef } from 'react';

class App extends Component {
  // 获取非受控组件的值
  // 1. 通过createRef创建一个ref对象
  // 2. 给元素绑定ref属性值为创建的ref对象
  // 3. 通过ref对象的current获取元素,再获取它的值
  mobileRef = createRef();

  getMobile = () => {
    console.log(this.mobileRef.current.value);
  };

  render() {
    return (
      <>
        <div>
          {/* 没有被state控制的表单原生认为是非受控组件 */}
          <input ref={this.mobileRef} type="text" placeholder="请输入手机号" />
          <button onClick={this.getMobile}>获取</button>
        </div>
      </>
    );
  }
}
export default App;
  • 12
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值