一、React 基本使用
- 先下载 react 和react-dom 的包 ,按以下命令安装
npm i react react-dom
- 创建一个Html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 1.引入js 文件 -->
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<div id="root"></div>
<script>
// 2. 创建React元素
/**
* 参数一:React 元素名称
* 参数二:React 元素属性
* 参数三:React 元素的子节点
*/
// const title = React.createElement('h1', null, 'hello Word');
const title = React.createElement('h1', {
title: '我是标题',
id: 'p1'
}, 'hello Word', React.createElement('span', null, '我是一个span'));
// 渲染 react
/**
* 参数一:要渲染的react 元素
* 参数二:挂载点
*/
ReactDOM.render(title, document.getElementById('root'))
</script>
</body>
</html>
二、React脚手架搭建及使用
-
初始化项目,命令:
npx create-react-app
+项目名字,(创建一个名为my-app的项目,示例:npx create-react-app my-app
),当出现Happy hacking 就成功了 -
启动项目,命令:
npm/yarn start
npx create-react-app my-app
npm/yarn start
2.1使用React脚手架初始化项目
npx 命令介绍
- npm v5.2.0 引入的一条命令
- 目的:提升包内提供的命令行工具的使用体验
- 原来:先安装脚手架包,在使用这个包中提供的命令
- 现在:无需安装脚手架包,就可以直接使用这个包提供的命令
补充说明
- 推荐使用:
npx create-react-app my-app
npm init react-app my-app
yarn create react-app my-app
2.1再脚手架中使用React
-
导入react 和react-dom两个包,找到index.js文件使用es6模块化语法导入
-
import React from 'react' import ReactDOM from 'react-dom'
-
调用React.createElement()方法创建react元素
-
调用ReactDOM.render()方法渲染react元素到页面
三、JSX的语法
- JSX的基本使用
- JSX中使用Javascript表达式
- JSX 的条件渲染
- JSX的列表渲染
- JSX的样式处理
1.JSX的基本使用
1.2JSX简介
JSX是JavaScript XML的简写,表示再JavaScript代码中写XML(HTML)格式的代码
优势:声明式语法更加直观、与HTML结构相同,降低学习成本,提升开发效率
JSX是React的核心内容
1.4 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>)
// 渲染
ReactDOM.render(list,document.getElementById('root'))
1.5JSX的样式处理
- 行内样式------style
const list = (<h1 style={{color:'red',backgroundColor:'yellow'}}>JSX的样式处理</h1>)
-
使用类名渲染使用,找到Css文件夹中的index.css文件
-
在此处添加css样式并在,index.js中导入
import React from 'react' import ReactDOM from 'react-dom' //引入css import './css/index.css' //jsx的样式处理 const list = ( <h1 className="title">你好 我是react</h1> ) // 渲染react元素 ReactDOM.render(list.document.getElementById('root'))
index.css
.title{
text-align:center;
}
1.6JSX的总结
-
JSX 是React的核心内容
-
JSX标识再JS代码中写HTML结构,是React声明式的体现。
-
使用JSX配合嵌入的JS表达式,条件渲染,列表渲染,可以描述任意UI结构
-
推荐使用className的方式给JSX添加样式
-
React完全利用JS语言自身的能力来编写UI,而不是造轮子增强HTML功能
备注:vue就是通过 v-if v-for 这种指令来增强html的功能 react 与vue的不同之处
四、React组件
1.React组件介绍
- 组件是react的一等公民,使用React就是在用组件
- 组件标识页面中的部分功能
- 组合多个组件实现完整的页面功能
- 特点:可复用、独立、可组合
2.React组件的两种创建方式
2.1使用函数创建组件
- 函数组件:使用JS的函数(或箭头函数)创建的组件
- 约定1:函数名称必须以大写字母开头
- 约定2:函数组件必须有返回值,表好似该组件的结构
- 如果返回值为null,标识不渲染任何内容
// 函数组件:
function Hello(){
return(
<div>我是第一个函数组件!</div>
)
}
// 箭头函数创建组件方式
const Hello=()=><div>我是第一个函数组件!</div>
ReactDOM.render(<Hello/>,document.getElementById('root'))
- 渲染函数组件:用函数名作为组件标签名
- 组件标签可以是单标签也可以是双标签
2.2使用类创建组件
- 类组件:使用ES6的class创建的组件
- 约定1:类名称也必须以大写字母开头
- 约定2:类组件应该继承React.Component父类,从而使用父类中提供的方法和属性
- 约定3:类组件必须提供render()方法
- 约定4:render()方法必须有返回值,表示该组件的结构
// 类组件
// 创建类组件
class Hello extends React.Component{
render(){
retrun <div>Hello Class Component!</div>
}
}
ReactDOM.render(<Hello />,document.getElementById('root'))
2.3抽离为独立JS文件
- 创建Hello.js
- 在Hello.js中导入React
- 创建组件(函数或类)
- 在Hello.js中导出该组件
- 在index.js中导入Hello组件
- 渲染组件
// Hello.js
import React from 'react'
class Hello extends React.Component{
render(){
return (
<div>hello 我是第一个被抽离出来的组件</div>
)
}
}
export default Hello
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// 导入Hello.js
import Hello from './Hello'
ReactDOM.render(<Hello />,document.getElementById('root'))
3.React事件处理
3.1事件绑定
- React 事件绑定语法与DOM事件语法相似
- 语法:on+事件名称={事件处理程序},比如:onClick={()=>{}}
- 注意:React事件采用驼峰命名法,比如:onMouseEnter、onFocus
// 类组件 事件绑定
class App extends React.Component{
handleClick(){
console.log('单击事件触发了')
}
render(){
return{
(<button onClick={this.handleClick}></button>)
}
}
}
// 函数组件 事件绑定
function App (){
function handleClick(){
console.log('单击事件触发了')
}
return (<button onClick={handleClick}></button>)
}
ReactDOM.render(<App />,document.getElementById('root'))
3.2事件对象
- 可以通过事件处理程序的参数获取到事件对象
- React 中的事件对象叫做:合成事件(对象)
- 合成事件:兼容所有浏览器,无需担心跨浏览器兼容性问题
class App extends React.Component{
handleClick(e){
// 阻止浏览器的默认行为
e.preventDefault()
console.log('单击事件触发了')
}
render(){
return{
(<a href="http://itcast.cn"
onClick={this.handleClick}
>传智播客</a>)
}
}
}
4.有状态组件和无状态组件
- 函数组件又叫做无状态组件,类组件又叫做有状态组件
- 状态(state)即数据
- 类组件有自己的状态,负责更新UI,让页面“动”起来
数据发生变化则使用类组件
5组件中的state和setState()
- state的基本使用
- setState()修改状态
5.1state的基本使用
- 状态(state)即数据,是组件内部的私有数据,只能在组件内部使用
- state的值是对象,表示一个组件中可以有多个数据
- 获取状态:this.state
class Hello extends React.Component{
// 复杂写法
constructor(){
super()
//初始化state
this.state = {
count:0
}
}
// 简单语法初始化state (推荐)
//state={
// count:0
//}
render(){
return (<div>有状态组件 {this.state.count}</div>)
}
}
5.2setState()修改状态
- 状态是可变的
- 语法:this.setState({要修改的数据})
- 注意:不要直接修改state中的值,这是错误的!!!
- setState() 作用:1,修改state 2,更新UI
- 思想:数据驱动视图
class App extends React.Component{
state={
count:0,
test:'a'
}
render(){
return (
<div>
<h1>计数器:{this.state.count}</div>
<button onClick={()=>{
this.setState({
count:this.state.count + 1
})
}}>+1</button>
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root'))
从JSX中抽离事件处理
-
JSX中掺杂过多JS逻辑代码,会显得非常混乱
-
推荐:讲逻辑抽离到单独的方法中,保证JSX结构清晰
6.事件绑定this指向
- 箭头函数
- Function.prototype.bind()
- class的实例方法
6.1箭头函数
- 利用箭头函数自身不绑定this的特点
- render()方法中的this为组件实例,可以获取到setState()
class App extends React.Component{
state={
count:0,
test:'a'
}
onIncrement(){
console.log('事件处理程序中的this',this)
this.setState({
count:this.state.count+1
})
}
render(){
return (
<div>
<h1>计数器:{this.state.count}</div>
<button onClick={()=>this.onIncrement()
}>+1</button>
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root'))
6.2Function.prototype.bind()
- 利用ES5中的bind方法,将事件处理程序中的this与组件实例绑定在一起
class App extends React.Component{
constructor(){
super()
this.sate={
count:0,
}
this.onIncrement = this.onIncrement.bind(this)
}
//事件处理程序
onIncrement(){
console.log('事件处理程序中的this',this)
this.setState({
count:this.state.count+1
})
}
render(){
return (
<div>
<h1>计数器:{this.state.count}</div>
<button onClick={this.onIncrement()}> +1 </button>
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root'))
6.3class的实例方法(推荐)
- 利用箭头函数形式的class实例方法
- 注意:该语法是实验性语法,但是,由于babel的存在可以直接使用
class App extends React.Component{
this.sate={
count:0,
}
//事件处理程序
onIncrement=()=>{
console.log('事件处理程序中的this',this)
this.setState({
count:this.state.count+1
})
}
render(){
return (
<div>
<h1>计数器:{this.state.count}</div>
<button onClick={this.onIncrement}>+1</button>
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root'))
7.表单处理
- 受控组件
- 非受控组件(DOM方式)
7.1受控组件
- HTML中的表单元素是可输入的,也就是有自己的可变状态
- 而,React中可变状态通常保存在state中,并且只能用过setState()方法来修改
- React将state与表单元素值value绑定到一起,有state的值来控制表单元素的值
步骤
- 在state中添加一个状态,作为表单元素的value值(控制表单元素值的来源)
- 给表单元素绑定change事件,将表单元素的值 设置为state的值(控制表单元素值的变化)
class App extends React.Component{
state={
txt:''
}
textChange=e=>{
this.setState({
txt:e.target.value
})
}
}
render(){
return (
<div>
<input type="text" value={this.state.txt} onChange={this.textChange} />
</div>
)
}
ReactDOM.render(<APP/>,document.getElementById('root'))
示例
class App extends React.Component{
state={
txt:'',
content:'',
city:'bj',
ischeck:true
}
textChange=e=>{
this.setState({
txt:e.target.value
})
},
handleContent=e=>{
this.setState({
txt:e.target.value
})
}
handleCity=e=>{
this.setState({
txt:e.target.value
})
}
handleCheck=e=>{
this.setState({
txt:e.target.cheked
})
}
}
render(){
return (
<div>
// 文本框
<input type="text" value={this.state.txt} onChange={this.textChange} /> <br/>
//文本域
<textarea value={this.state.content} onChange={this.handleContent} ></textarea> <br/>
// 下拉框
<select value={this.state.city} onChange={this.handleCity}>
<option value="sh">上海</option>
<option value="bj">北京</option>
<option value="sz">深圳</option>
</select> <br/>
//复选框
<input type="checkbox" checked={this.state.
ischeck} onChange={this.handleCheck} />
</div>
)
}
ReactDOM.render(<APP/>,document.getElementById('root'))
多表单元素优化步骤:
- 给表单元素添加name属性,名称与state相同
- 根据表单元素类型获取对应值
- 在change事件处理程序中通过[name]来修改对应的state
// 优化后
class App extends React.Component{
state={
txt:'',
content:'',
city:'bj',
ischeck:true
}
formChange=e=>{
const target = e.target
const value = e.target.type === "checkbox" ? e.target.checked:e.target.value
const name = target.name
this.setState({
[name]:value
})
}
}
render(){
return (
<div>
// 文本框
<input type="text"
name="txt"
value={this.state.txt}
onChange={this.formChange} /> <br/>
//文本域
<textarea
value={this.state.content}
name="content"
onChange={this.formChange} ></textarea> <br/>
// 下拉框
<select value={this.state.city}
name="city" onChange={this.formChange}>
<option value="sh">上海</option>
<option value="bj">北京</option>
<option value="sz">深圳</option>
</select> <br/>
//复选框
<input type="checkbox"
name="ischeck"
checked={this.state.ischeck}
onChange={this.formChange} />
</div>
)
}
ReactDOM.render(<APP/>,document.getElementById('root'))
7.2非受控组件
- 说明:借助于ref,使用原生DOM方式来获取表单元素值
- ref的作用:获取DOM或组件
使用步骤:
-
调用React.createRef()方法创建一个ref 对象
constructor(){ super() this.txtRef = React.createRef() }
-
将创建好的ref对象添加到文本框中
<input type="text" ref={this.txtRef} />
-
通过ref 对象获取到文本框的值
console.log(this.txtRef.current.value)