react用于动态构建用户界面的js库,由facebook开源基于mvc框架
- 特点:声明式,组件化,一次学习随处使用(支持多端)
- 安装:npm i react react-dom
- 使用:
- ①引入react和reactDom的js文件
import React from "react";
import ReactDOM from "react-dom/client";
- ②创建react元素(react.creatElement(元素名称,属性,子节点)
const root = ReactDOM.createRoot(document.getElementById("root"));
- ③通过reactDom.render(要渲染的节点,挂载点)进行页面渲染
root.render(<Parent />);//<Parent />是组件
- 创建脚手架:npm create-react-app 项目名
- 运行项目:npm start
- 在脚手架中使用react
JSX
一个 JavaScript 的语法扩展,可能会使人联想到模板语言,但它具有 JavaScript 的全部功能。
JSX语法:
- ①创建变量=标签
- ②reactDom.render(变量,挂载点)
const element = <h1>Hello, world</h1>;
react可以使用jsx的原因是因为label编译处理(@babel/preset-react)
注意点:
- ①属性名使用小驼峰命名法
- ②特殊属性名:class->className,for->htmlFor,tabundex->tabIndex
- ③若没有子节点,可以直接使用/>结束
- ④使用()包裹jsx代码
在jsx使用js:{js表达式}
注意点:
- ①在{}中可以使用任意js表达式
- ②jsx自身也是js表达式
- ③js中的对象是一个特例,一般在style中会用
- ④语句不能写在{}中,例如if/for
jsx的条件渲染:
可以使用if,三元,逻辑与运算等进行条件渲染(函数的调用也是表达式)
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Greeting isLoggedIn={false} />);
jsx的列表渲染:
使用map的方法实现,注意列表渲染需要添加唯一属性key,一般map遍历谁就给谁加,
<ul>{数组.map(item=><li key={item}></li>)}</ul>
注意点:避免使用索引号作为key
jsx样式渲染:
- ①行内样式style
- ②className(推荐) className=类名,然后在css文件写样式
总结:
- ①jsx是react核心
- ②jsx表示在js中写html结构,是react声明式的表现
- ③使用jsx配合嵌入式的js表达式条件渲染,列表渲染可以描述任意ui结构
- ④推荐使用className的方式给jsx添加样式
- ⑤react完全利用了js语言自身的能力来编写ui而不是造轮子增强html的功能使用react就是在使用组件
创建组件的两种方式
①函数组件:使用函数创建组件
三条约定:
- 函数名大写字母开头
- 函数组件必须有返回值,代表该组件的结构
- 返回值为null则代表不渲染任何内容
- 渲染时函数名即为组件名,可以是单标签也可以是双标签
②类组件:使用class创建的组件
三条约定:
- 类名必须用大写字母开头
- 类组件应继承React.component父类
- 类组件必须提供render方法
- render方法必须有return代表组件结构
抽离为独立的js文件
- 创建js文件
- 导入react
- 创建组件(函数或者类)
- 导出
- 导入使用
事件绑定
- 语法:on+事件名={事件处理函数}
- 类组件里声明方法,使用this.方法名
- 函数组件里声明函数,使用函数名
//函数组件(无状态组件)
function Form() {
function handleSubmit(e) {
e.preventDefault(); console.log('You clicked submit.');
}
return (
<form onSubmit={handleSubmit}>
<button type="submit">Submit</button>
</form>
);
}
//ES6 class组件(状态组件)
class Form extends React.Component {
handleSubmit = (e) => {
e.preventDefault();
console.log('You clicked submit.');
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<button type="submit">Submit</button>
</form>
);
}
}
事件对象
- 阻止默认行为:e.preventDefault(不能使用return false)
- 有状态组件和无状态组件(状态即为数据)
- 函数组件称为无状态组件:负责数据展示(静态)
- 类组件称为有状态组件:负责更新ui(动态)
- 组件中的state和setState(状态) 复杂写法:
class 组件名 extends React.Component {
constructor() {
super(this.props);
this.state = {
form: { name: "", common: "" },
属性: 属性值
};
}
//生命周期函数
//自定义的方法
//推荐使用箭头函数,确保this的指向
render() {
return (
需要渲染的内容
);
}
}
简单写法:
class 组件名 extends React.Component {
state = {
form: { name: "", common: "" },
属性: 属性值
};
//生命周期函数
//自定义的方法
//推荐使用箭头函数,确保this的指向
render() {
return (
需要渲染的内容
);
}
}
- state的基本使用:this.state.数据名
修改state:setState方法
语法:this.setState({属性:新值})
- 注意:不要直接修改state,这个是错误的
- 思想:数据驱动视图 推荐:将逻辑代码抽离jsx
注意:render内的this指向组件实例,解决事件处理函数中this指向问题
- 绑定事件时使用箭头函数:onClick={()=>this.方法名}
- 利用bind方法:在construct方法里,this.方法名=this.方法名.bind(this)
- class内部,事件使用箭头函数
表单元素-受控组件
步骤:
- ①在state里面添加状态,并绑定表单的value。 value={this.state.txt}
- ②给表单绑定change事件,将表单元素的值设置为state的值(控制表单元素值的变化)
onChange={e=>this.setState({txt:e.taeget.value})}
多表单优化-封装统一的事件处理函数
步骤:
- ①为表单添加name属性,属性值为绑定的state的值
- ②根据表单类型e.target.type是否是checkbox判断取value还是checked
- ③change事件中通过[e.target.name]修改对应的state
表单处理-非受控组件
- ①创建ref对象
this.refTxt=React.createRef()
- ②在表单中绑定
控件上 ref="this.ref"
- ③获取控件内容
this.refTxt.current.value
组件通信
- 组件的props
- 传递数据:给组件添加属性
- 接受数据:函数组件使用props.属性名,类组件使用this.props.属性名
- 特点:
- ①可以传递任何类型数据,包括函数和组件
- ②props只可读,不能修改
- ③如果使用类组件,render可以获取到this.props,但是如果写了构造函数,推荐并必须把props传给super中,否则构造函数中拿不到props
综合练习: 组件通信+受控组件表单处理