小工具知识网

当前位置: 首页 > 行业知识 > react-组件基础

行业知识

react-组件基础

2026-11-02 11:04:57 来源:互联网转载

1.目标

能够使���函数创建组件

能够使用class创建组件

能够给React元素绑定事件

能够使用state和setState()

能够处理事件中的this指向问题

能够使用受控组件方式处理表单

2.目录

React组件介绍

React组件的两种创建方式

React事件处理

有状态组件和无状态组件

组件中的state和setState()

事件绑定this指向

表单处理

3.react组件介绍

组件是React的一等公民,使用React就是在用组件

组件表示页面中的部分功能

组合多个组件实现完整的页面功能

特点:可复用、独立、可组合

4.react组件的两种创建方式

A. 使用函数创建组件

B. 使用类创建组件

4.1 使用函数创建组件

A. 函数组件:使用JS的函数(或箭头函数)创建的组件

B. 约定1:函数名称必须以大写字母开头

C. 约定2:函数组件必须有返回值,表示该组件的结构

D. 如果返回值为null,表示不渲染任何内容

function Hello(){return (这是我的第一个函数组件)}

A. 渲染函数组件:用函数名作为组件标签名

B. 组件标签可以是单标签也可以是双标签

ReactDOM.render(,document.getElementById('root'))

4.2 使用类创建组件

A. 类组件:使用ES6的class创建的组件

B. 约定1:类名称也必须以大写字母开头

C. 约定2:类组件必须继承React.Component父类,从而可以使用父类中提供的方法或属性

D. 约定3:类组件必须提供render()方法

E. 约定4:render()方法必须有返回值,表示该组件的结构

class Hello1 extends React.Component{render(){return (我是一个类组件)}}ReactDOM.render(,document.getElementById('root'))

4.3 抽离为单独JS文件

A. 思考:项目中的组件多了之后,该如何组织这些组件呢?

B. 选择一:将所有组件放在同一个JS文件中

C. 选择二:将每个组件放到单独的JS文件中

D. 组件作为一个独立的个体,一般都会放到一个单独的JS文件中

E. 抽离步骤:

\1. 创建Hello.js

\2. 在Hello.js中导入React

\3. 创建组件(函数或类)

\4. 在Hello.js中导出该组件

\5. 在index.js中导入Hello组件

\6. 渲染组件

5.React事件处理

\1. 事件绑定

\2. 事件对象

5.1 事件绑定

A. React事件绑定语法与DM事件语法相似

B. 语法:on+事件名称=[事件处理程序],比如:onClick={()=>{}}

C. 注意:React事件采取驼峰命名法,比如:onMouseEnter、onFocus

D. 在函数组件绑定事件:

Index.js(函数事件绑定)

// 函数组件事件绑定function Hello() {  function clickHandle() {    console.log("函数事件触发了");  }  return clickHandle}点击触发函数事件;}ReactDOM.createRoot(document.getElementById("root")).render();

index.js(类事件绑定)

// 类事件绑定class Hello2 extends React.Component {  clickHandle() {    console.log("类事件触发了");  }  render() {    return this.clickHandle}点击触发类事件;  }}ReactDOM.createRoot(document.getElementById("root")).render();

区别:

5.2 事件对象

A. 可以通过事件处理程序的参数获取到事件对象

B. React中的事件对象叫做:合成事件(对象)

C. 合成事件:兼容所有浏览器,无需担心跨浏览器兼容性问题

// 事件对象class App extends React.Component {  clickHandel(e) {    // 阻止浏览器默认行为    e.preventDefault();    console.log("点击事件触发了");  }  render() {    return (      this.clickHandel}        百度          );  }}ReactDOM.createRoot(document.getElementById("root")).render();

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

A. 函数组件又叫做无状态组件,类组件又叫做有状态组件

B. 状态(state)即数据

C. 函数组件没有自己的状态,只负责数据展示(静)

D. 类组件有自己的状态,负责更新UI,让页面”动”起来

比如计算器案例中,点击按钮让数值加1。0和1就是不同时刻的状态,而由0变为1就表示状态发生了变

化。状态变化后,UI也要相应的更新。React中想要实现该功能,就要使用有状态组件来完成。

7.组件中的state和setState

A. state的基本使用

B. setState()修改状态

7.1 state的基本使用

A. 状态(state)即数据,是组件内部的私有数据,只能在组件内部使用

B. state的值是对象,表示一个组件中可以有多个数据

C. 状态即数据

D. 状态是私有的,只能在组件内部使用

E. 通过this.state来获取状态

// 有状态组件class Hello3 extends React.Component {  constructor() {    super(); // 必须写  }  state = {    count: 0,  };  render() {    return (              有状态组件        

计数器:{this.state.count}

); }}ReactDOM.createRoot(document.getElementById("root")).render();

7.2 setState()修改状态

A. 状态是可变的

B. 语法:this.setState({要修改的数据})

C. 注意:不要直接修改state中的值,这是错误的!!!!

D. setState()作用:1.修改state 2.更新UI

E. 思想:数据驱动视图

// 有状态组件class Hello3 extends React.Component {  constructor() {    super(); // 必须写  }  state = {    count: 0,  };  render() {    return (              有状态组件        

计数器:{this.state.count}

() = { this.setState({ count: this.state.count + 1 }); }} > +1 ); }}ReactDOM.createRoot(document.getElementById("root")).render();

7.3 从JSX中抽离事件处理程序

A. JSX中掺杂过多JS逻辑代码,会显得非常混乱

B. 推荐:将逻辑抽离到单据的方法中,保证JSX结构清晰

// 有状态组件class Hello3 extends React.Component {  constructor() {    super(); // 必须写  }  state = {    count: 0,  };  onIncrement() {     console.log(this, "抽离出来的this");    this.setState({      count: this.state.count + 2,    });  }  render() {    return (              有状态组件        

计数器:{this.state.count}

() = { console.log(this, "函数式事件触发的this"); this.setState({ count: this.state.count + 1 }); }} > +1 this.onIncrement}+2 ); }}ReactDOM.createRoot(document.getElementById("root")).render();

A. 原因:事件处理程序中this的值为undefined—抽离出来的方法用箭头函数可解决

B. 希望:this指向组件实例(render方法中的this即为组件实例)

把state放在,构造函数里面

8.事件绑定this指向

A. 抽离出的事件处理函数使用箭头函数

B. Function.prototype.bind() 【在构造函数中使用.bind(this)来绑定this上下文】

C. 在render方法中使用箭头函数来调用onIncrement,但这样每次渲染都会创建一个新的函数,可能会影响性能

8.1 箭头函数

A. 利用箭头函数自身不绑定this的特点

B. Render()方法中的this为组件实例,可以获取到setState()

8.2 在构造函数中使用.bind(this)来绑定this上下文–Function.prototype.bind()

8.3 在render方法中使用箭头函数来调用onIncrement,但这样每次渲染都会创建一个新的函数,可能会影响性能

() = this.onIncrement()}>+2

9.表单处理

\1. 受控组件

\2. 非受控组件(DOM方式)

9.1 受控组件

A. HTML中的表单元素是可输入的,也就是有自己的可变状态

B. 而,React中可变状态通常保存在state,并且只能通过setState()方法来修改

C.React将state与表单元素值value绑定到一起,由state的值来控制表单元素的值

D. 受控组件:其值受到React控制的表单元素

E. 步骤

\1. 在state中添加一个状态,作为表单元素的value值(控制表单元素值的来源)

\2. 给表单元素绑定change事件,将表单元素的值设置为state的值(控制表单元素值的变化)

class Hello4 extends React.Component {  constructor() {    super();    this.state = {      txt: "默认值",    };  }  inputHandle = (e) => {    this.setState({      txt: e.target.value,    });  };  render() {    return (              文本的值:{this.state.txt}        
this.state.txt} onChange={this.inputHandle} ); }}ReactDOM.createRoot(document.getElementById("root")).render();

示例:

A.文本框、富文本框、下拉框

B.复选框

class Hello4 extends React.Component {  constructor() {    super();    this.state = {      txt: "默认值",      content: "",      city: "zj",      isChecked: true,    };  }  handleChange1 = (e) => {    this.setState({      txt: e.target.value,    });  };  handleChange2 = (e) => {    this.setState({      content: e.target.value,    });  };  handleChange3 = (e) => {    this.setState({      city: e.target.value,    });  };  handleChange4 = (e) => {    console.log(e, "e4");    this.setState({      isChecked: e.target.checked,    });  };  render() {    return (              {/* 输入框 */}        文本的值:{this.state.txt}        this.state.txt}          onChange={this.handleChange1}                
{/* 文本框 */} 文本框的值:{this.state.content} this.state.content} onChange={this.handleChange2}
{/* 下拉框 */} 下拉框的值:{this.state.city} this.state.city} onChange={this.handleChange3} 浙江 江苏 上海 北京
{/* 复选框 */} 复选框的值:{this.state.isChecked} this.state.isChecked} onChange={this.handleChange4} ); }}ReactDOM.createRoot(document.getElementById("root")).render();

9.1.1 多表单元素优化

A. 问题:每个表单元素都有一个单独的事件处理程序处理太繁琐

B. 优化:使用一个事件处理程序同时处理多个表单元素

9.1.2 多表单元素优化步骤

A. 给表单元素添加name属性,名称与state相同

B. 根据表单元素类型获取对应值

C. 在change事件处理程序中通过[name]来修改对应的state

class Hello4 extends React.Component {  constructor() {    super();    this.state = {      txt: "默认值",      content: "",      city: "zj",      isChecked: true,    };  }  handleForm = (e) => {    const value =      e.target.type === "checkbox" ? e.target.checked : e.target.value;    this.setState({      [e.target.name]: value,    });  };  render() {    return (              {/* 输入框 */}        文本的值:{this.state.txt}        this.state.txt}          onChange={this.handleForm}                
{/* 文本框 */} 文本框的值:{this.state.content} this.state.content} onChange={this.handleForm}
{/* 下拉框 */} 下拉框的值:{this.state.city} this.state.city} name="city" onChange={this.handleForm} 浙江 江苏 上海 北京
{/* 复选框 */} 复选框的值:{this.state.isChecked} this.state.isChecked} onChange={this.handleForm} ); }}ReactDOM.createRoot(document.getElementById("root")).render();

9.2 非受控组件

A. 说明:借助于ref,使用原生DOM方法来获取表单元素值

B. ref的作用:获取DOM或组件

C. 使用步骤:

  1. 调用React.createRef()方法创建一个ref对象
  2. 将创建好的ref对象添加到文本框中
  3. 通过ref对象获取到文本框的值
class Hello6 extends React.Component {  constructor() {    super();    // 创建Ref    this.textRef = React.createRef();  }  getText = () => {    console.log(this.textRef);    console.log(this.textRef.current.value);  };  render() {    return (              this.textRef}        this.getText}获取文本框的值          );  }}ReactDOM.createRoot(document.getElementById("root")).render();

10.react组件基础-案例评论列表

index.js

class Comment extends React.Component {  constructor() {    super();    // 初始化值      this.state = {      userName: "",      userContent: "",      comments: [        { id: 1, name: "周可可", content: "大家好,我是周可可~~" },        { id: 2, name: "周嫑嫑", content: "每没有人能欺负周可可!!!" },        { id: 3, name: "周深", content: "大家好,我是周深~~" },        { id: 4, name: "周浅", content: "大家好,我是周浅~~" },      ],    };  }  // 数据展示  renderList = () => {    return this.state.comments.length == 0 ? (      暂无评论,快去发布吧~    ) : (              
    {this.state.comments.map((item) => ( item.id} 评论人:{item.name}
    评论内容:{item.content} ))}
); }; // 数据响应式 changeForm = (e) => { const { name, value } = e.target; this.setState({ [name]: value, }); }; // 添加 addComment = () => { let { userName, userContent, comments } = this.state; // 非空校验 if (userName.trim() == "" || userContent.trim() == "") { return alert("用户名或评论内容不能为空!"); } const newComments = [ { id: comments.length > 0 ? comments.length + 1 : 1, name: userName, content: userContent, }, ...comments, ]; console.log(newComments, "newComments"); this.setState({ comments: newComments }); // 清空数据 this.state.userName = ""; this.state.userContent = ""; }; render() { const { userName, userContent } = this.state; return (

评论

userName} onChange={this.changeForm}
{ marginBottom: "10px" }} 10} cols={50} className="contentTextarea" value={userContent} onChange={this.changeForm} this.addComment}发布评论 { textAlign: "center" }}评论详情 {this.renderList()} ); }}ReactDOM.createRoot(document.getElementById("root")).render( );

index.css

.appp {  width: 35%;  height: 700px;  border: 1px solid gray;  padding-left: 50px;}.appp h1 {  text-align: center;}.userIpt {  width: 40%;}.contentDetailBox {  height: 300px;  overflow-y: scroll;}

上一篇:drink怎么读发音语音?

下一篇:怎么检查邮件服务器?