什么是React?
React是一个用于构建用户界面的JavaScript库
用户界面:HTML页面(前端)
react主要用来写HTML页面,或构建Web应用。
如果从MVC的角度来看,React仅仅是视图层(V),也就是只负责视图的渲染,而并非提高了完整的M和C的功能。
React的特点
1 声明式
2 基于组件
3 学习一次,随处使用
使用React可以开发Web应用
使用React可以开发移动端原生应用(react-native)
使用React可以开发VR(虚拟现实)应用(react360)
React的安装
安装命令:npm i react react-dom
react包是核心,提高创建元素,组件等功能
react-dom包提高DOM相关功能等
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React
基本使用
</title>
</head>
<body>
<div id="root"></div>
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<script>
//创建react元素
// 参数一:元素名称
// 参数二:元素属性 可以用对象来{title:'我是标题',id:'p1'}
// 第三个及其以后的节点:元素的子节点
const title = React.createElement('h1', null, 'hello react',React.createElement('span', null, '我是span'))
// 渲染react元素
// 参数一:要渲染的react元素
// 参数二:挂载点
ReactDOM.render(title, document.getElementById('root'))
</script>
</body>
</html>
React脚手架
使用React脚手架初始化项目
1 初始化项目,命令:npx create-react-app my-app
推荐使用 npx create-react-app my-app
其他的命令: npm init react-app my-app
2 启动项目 npm start
React脚手架的使用
1 导入react和react-dom两个包
import React from 'react'
import ReactDOM from 'react-dom'
2 调用React.createElement()方法创建react元素
3 调用ReactDOM.render()方法渲染react元素到页面中
JSX注意点
1 React元素的属性名使用驼峰命名法
2 特殊属性名: class->className、 for->htmlFor、 tabindex->tabIndex
3 没有子节点的React元素可以用</>结束
4 推荐:使用小括号包裹JSX,从而避免JS中的自动插入分号陷阱
const title1 = (
<h1 className="title">
hello JSX <span />{" "}
</h1>
);
ReactDOM.render(title1, document.getElementById("root"));
JSX中使用javascript表达式
语法: {js表达式}
const name = "张三";
const dv=(
<p>{name}</p>
)
JSX的条件渲染
// 条件渲染
const isLoading=false
const loadData=()=>{
//也可以用三目表达式
if(isLoading){
return <div>加载中。。。</div>
}
return <div>数据加载完成,此处显示加载后的数据</div>
}
const title1 = (
<h1 className="title">
hello JSX <span />{" "}
条件渲染:
{loadData()}
</h1>
);
ReactDOM.render(title1, document.getElementById("root"));
逻辑运算符
const loadData=()=>{
return isLoading && (<h1>loading....</h1>)
}
JSX的列表循环
// 列表渲染
const songs = [
{ id: 1, name: '痴心绝对' },
{ id: 2, name: '月亮代表我的心' },
{ id: 3, name: '小幸运' }
]
const list = (
<ul>
{songs.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
)
JSX样式处理
两种方式:style 是{{ }}; className
//引入css
import './index.css'
const title1 = (
<h1 className="title" style={{ color: 'red' }}>
hello JSX
</h1 >
);
index.css
.title{
font-size:14px;
}
JSX组件
React组件介绍
组件表示页面中部分功能,组合多个组件实现完整的页面功能;特点:可复用、独立、可组合
创建方式
1 使用函数创建组件
函数组件:使用JS的函数(或箭头函数)创建组件
约定1:函数名称必须以大写字母开头,React据此区分组件和普通的React元素
约定2:函数组件必须有返回值,表示该组件的结构。如果返回值为null,表示不渲染任何内容
渲染函数组件:用函数名作为组件标签名
组件标签可以是单标签也可以是双标签
function Hello() {
//return null
return <h1>hello,我是React</h1>
}
// 箭头函数
const Hello1=()=><h1>hello,我是React</h1>
ReactDOM.render(<Hello></Hello>, document.getElementById("root"));
2 使用类创建组件
类组件:使用es6的class创建的组件
约定1: 类名称必须以大写字母开头
约定2:类组件应该继承React.Component父类,从而可以使用父类中提供的方法或属性
约定3:类组件必须提供render()方法
约定4:render()方法必须有返回值,表示该组件的结构
//创建类组件
class Hello extends React.Component {
render() {
return (
<div>我是第一个类组件</div>
)
}
}
ReactDOM.render(<Hello />, document.getElementById("root"));
3 抽离为独立的js文件
1 创建hello.js文件
2 在Hello.js中导入React
3 创建组件(函数或类)
4 在Hello.js中导出该组件
比如创建Hello.js文件
import React from "react";
//创建组件
class Hello extends React.Component {
render() {
return (
<div>我是第一个封装的组件</div>
)
}
}
export default Hello
5 引入组件并渲染,在index.js文件中引入Hello
import Hello from './Hello'
ReactDOM.render(<Hello />, document.getElementById("root"));
事件绑定
React 事件绑定语法与DOM事件语法相似
语法:on+事件名称={事件处理程序},比如,onClick={()=>{}}
注意:React事件采用驼峰命名法,比如:onMouseEnter、onFocus
class Hello extends React.Component {
handlerClick() {
console.log('单击事件触发了')
}
render() {
return (
<div>
<div>我是第一个封装的组件</div>
<button onClick={this.handlerClick}>点击</button>
</div>
)
}
}
在函数中声明
function App() {
function handlerClick() {
console.log('单击事件')
}
return (
<button onClick={handlerClick}>函数点击</button>
)
}
ReactDOM.render(<App />, document.getElementById("root"));
事件对象
可以通过事件处理程序的参数获取到事件对象
React中的事件对象叫做:合成事件(对象)
合成事件:兼容所有浏览器,无需担心跨浏览器兼容性问题
function aclickFun(e) {
e.preventDefault()
console.log('a标签事件')
}
有状态组件和无状态组件
函数组件又叫做无状态组件,类组件又叫做有状态组件
状态(state)即数据
函数组件没有自己的状态,只负责数据展示(静)
类组件有自己的状态,负责更新UI,让页面"动"起来
具体来说,用户改变了数据,页面也要更新,就需要有状态组件
组件中的state和setState
state的基本使用
状态(state)即数据,是组件内部的私有数据,只能在组件内部使用
state的值是对象,表示一个组件中可以有多个数据
constructor() {
super()
//初始化state
this.state = {
count: 0
}
}
//简化语法
state = {
count: 0
}
setState()修改状态
状态时可变的
语法:this.setState({要修改的数据})
注意:不要直接修改state中的值,这是错误的
this.setState({count:this.state.count+1})
//创建组件
class Hello extends React.Component {
// constructor() {
// super()
// //初始化state
// this.state = {
// count: 0
// }
// }
//简化语法
state = {
count: 0
}
handlerClick = () => {
this.setState({ count: this.state.count + 1 })
console.log('单击事件触发了')
}
render() {
return (
<div>
<p>计数器:{this.state.count}</p>
<button onClick={this.handlerClick}>点击</button>
</div>
)
}
}
export default Hello
事件绑定this指向
1 箭头函数
handlerClick() {
this.setState({ count: this.state.count + 1 })
console.log('单击事件触发了')
}
render() {
return (
<div>
<p>计数器:{this.state.count}</p>
<button onClick={() => this.handlerClick()}>点击</button>
</div>
)
}
2 Function.prototype.bind()
constructor() {
super()
this.handlerClick = this.handlerClick.bind(this)
}
class的实例方法
利用箭头函数形式的class实例方法
hanclerClick=()=>{ this.setState({count:this.state.count+1}) }
表单处理
受控组件
HTML中的表单元素是可输入的,也就是有自己的可变状态
而React中可变状态通常是保存在state中,并且只能通过setState()方法来修改
React将state与表单元素值value绑定到一起,由state的值来控制表单元素的值
changeFun = (e) => {
this.setState(
{ txt: e.target.value }
)
}
<input type="text"
value={this.state.txt}
onChange={this.changeFun}
/>
常见的表单属性
添加name属性,后续需要这个name属性修改state中的值,
<input type="text"
name='txt'
value={this.state.txt}
onChange={this.changeFun}
/>
<textarea name='content' value={this.state.content} onChange={this.changeFun}></textarea>
<select name='city' value={this.state.city} onChange={this.changeFun}>
<option value="sh">上海</option>
<option value="bj">北京</option>
<option value="hz">杭州</option>
</select>
<input name='isCheck' type="checkbox" checked={this.state.isCheck} onChange={this.changeFun} />
通过同一个方法绑定事件
因为复选框是需要绑定checked值,所有需要判断一下
changeFun = (e) => {
const value = e.target.type === 'checkbox' ? e.target.checked : e.target.value
this.setState(
{ [e.target.name]: value }
)
}
非受控组件
说明:借助于ref,使用原生DOM方法来获取表单元素值
ref的作用:获取DOM或组件
使用步骤:
1 调用React.createRef()方法创建一个ref对象
constructor(){
super()
this.txtRef=React.createRef()
}
2 将创建好的ref对象添加到文本框中
<input type="text" ref={this.txtRef} />
3 通过ref对象获取到文本框的值
console.log(this.txtRef.current.value)
综合案例:发表评论
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
class App extends React.Component {
state = {
comments: [],
userContent: "",
userName: "",
};
handlerChange = (e) => {
const { name, value } = e.target;
this.setState({ [name]: value });
};
faBuFun = () => {
const { comments, userName, userContent } = this.state;
if (!userContent.trim() || !userName.trim()) {
alert("请填入内容");
return false;
}
const newComments = [
{ id: Math.random(), name: userName, content: userContent },
...comments,
];
this.setState({
comments: newComments,
userContent: "",
userName: "",
});
console.log(this.state.comments);
};
renderList() {
return this.state.comments.length === 0 ? (
<div className="no-comment">暂无评论,快去评论吧</div>
) : (
<ul>
{this.state.comments.map((item) => (
<li key={item.id}>
<h3>评论人:{item.name}</h3>
<p>评论内容:{item.content}</p>
</li>
))}
</ul>
);
}
render() {
return (
<div className="app">
<div>
<input
onChange={this.handlerChange}
name="userName"
className="user"
type="text"
placeholder="请输入评论人"
value={this.state.userName}
/>
<br />
<textarea
name="userContent"
className="content"
cols="30"
rows="10"
placeholder="请输入评论内容"
value={this.state.userContent}
onChange={this.handlerChange}
/>
<br />
<button onClick={this.faBuFun}>发表评论</button>
</div>
{/* 通过条件渲染决定渲染什么内容 */}
{this.renderList()}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));