function Hello(){
return (
<div>第一个函数组件</div>
)
}
渲染函数组件:用函数名作为组件标签名
组件标签可以是单标签也可以是双标签
// function Hello() {
// return (
// 第一个组件
// )
// }
// 箭头函数
const Hello = () => <div> 第一个函数组件 </div>
// 渲染组件
ReactDOM.render(< Hello />, document.getElementById('root'))
类组件:使用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'))
组件作为一个独立的个体,一般都会放到一个单独的JS文件中。
步骤:
// Hello.js
import React from 'react'
class Hello extends React.Component {
render (){
return <div>Hello Class Component!</div>
}
}
// 导出Hello组件
export default Hello
// index.js
import Hello from './Hello'
// 渲染导入的Hello组件
ReactDOM.render(<Hello />, document.getElementById('root'))
语法:on+事件名称={事件处理程序}
,比如onClick = {()=>{}}
注意:React事件采用驼峰命名法
,比如:onMouseEhter、onFocus
// // 函数事件
// function App() {
// function handleClick() {
// console.log('类组件中的事件绑定,单击事件触发了')
// }
// return (
//
// )
// }
// 类事件
class App extends React.Component {
handleClick() {
console.log('函数组件中的事件绑定,单击事件触发了')
}
render() {
return (
<button onClick={this.handleClick}>类事件绑定</button>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
事件处理函数的参数
获取到事件对象stopPropagation()
和 preventDefault()
nativeEvent
属性来进行获取// 类事件
class App extends React.Component {
// 事件处理程序
handleClick(e) {
e.preventDefault()
console.log('a标签的单击事件触发了')
}
render() {
return (
<a href="http://itcast.cn/" onClick={this.handleClick}>传智播客</a>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
无状态组件
,类组件又叫做有状态组件
状态( state )即数据,是组件内部的私有数据,只能在组件内部使用
state的值是对象,表示一个组件中可以有多个数据
class App extends React.Component {
// // 初始化状态
// constructor() {
// super();
// // 初始化state
// this.state = {
// count: 0
// }
// }
// 简化语法
state = {
count: 0
}
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
状态即数据
状态是私有的,只能在组件内部使用
通过this.state
来获取状态
状态是可变的
语法:this.setState({要修改的数据)
注意:不要直接修改state中的值,这是错误的! ! !
setState()作用:1.修改state; 2.更新UI
思想:数据驱动视图
/*
setState()的基本使用
*/
class App extends React.Component {
// 简化语法
state = {
count: 0
}
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
<button onClick={() => {
this.setState({
count: this.state.count + 1
})
// 错误演示
// this.state.count += 1
}}>+1</button>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
问题:
使用JSX抽离单独的程序处理时,this为undefined
class App extends React.Component {
// 简化语法
state = {
count: 0
}
// 事件处理程序
onIncrement() {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
<button onClick={this.onIncrement}>+1</button>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
利用箭头函数自身不绑定this的特点
render()
方法中的this为组件实例,可以获取到setState()
class App extends React.Component {
// 简化语法
state = {
count: 0
}
// 事件处理程序
onIncrement() {
this.setState({ // 这里的this指向下面箭头函数的this
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1> 计数器: {this.state.count} </h1>
<button onClick={() => this.onIncrement()} > +1 </button>
{/* () => this.onIncrement()才是真正的事件处理程序
这里的this就是所求实例
*/}
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
利用ES5中的bind方法,将事件处理程序中的this与组件实例绑定到起
class App extends React.Component {
// 简化语法
state = {
count: 0
}
constructor() {
super()
this.onIncrement = this.onIncrement.bind(this)
}
// 事件处理程序
onIncrement() {
this.setState({ // 这里的this指向下面箭头函数的this
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1> 计数器: {this.state.count} </h1>
<button onClick={this.onIncrement} > +1 </button>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
利用箭头函数形式的class实例方法
注意:该语法是实验性语法,但是,由于babel的存在可以直接使用
class App extends React.Component {
// 简化语法
state = {
count: 0
}
// 事件处理程序
onIncrement = () => {
this.setState({ // 这里的this指向下面箭头函数的this
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1> 计数器: {this.state.count} </h1>
<button onClick={this.onIncrement} > +1 </button>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
HTML中的表单元素是可输入的,也就是有自己的可变状态
React中可变状态通常保存在state中,并且只能通过setState()
方法来修改
React将state 与表单元素值value绑定到一起,由state的值来控制表单元素的值
受控组件:其值受到React控制的表单元素。
步骤
class App extends React.Component {
// 简化语法
state = {
txt: ''
}
// 事件处理程序
handleChange = e => {
this.setState({ // 这里的this指向下面箭头函数的this
txt: e.target.value
})
}
render() {
return (
<div>
<input type="text" value={this.state.txt} onChange={this.handleChange} />
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
文本框、富文本框、下拉框操作value属性
复选框操作checked属性
class App extends React.Component {
// 简化语法
state = {
txt: '',
content: '',
city: 'bj',
isChecked: false
}
// 事件处理程序
handleChange = e => {
this.setState({ // 这里的this指向下面箭头函数的this
txt: e.target.value
})
}
// 处理富文本框的变化
handleContentChange = e => {
this.setState({
content: e.target.value
})
}
// 处理下拉框的变化
handleCityChange = e => {
this.setState({
city: e.target.value
})
}
// 处理复选框的变化
handleCheckedChange = e => {
this.setState({
isChecked: e.target.checked
})
}
render() {
return (
<div>
{/* 文本框 */}
<input type="text" value={this.state.txt} onChange={this.handleChange} />
<br />
{/* 富文本框 */}
<textarea value={this.state.content} onChange={this.handleContentChange}></textarea>
<br />
{/* 下拉框 */}
<select value={this.state.city} onChange={this.handleCityChange}>
<option value="sh">上海</option>
<option value="bj">北京</option>
<option value="hz">杭州</option>
</select>
<br />
{/* 复选框 */}
<input type="checkbox" checked={this.state.isChecked} onChange={this.handleCheckedChange} />
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
问题:每个表单元素都有一个单独的事件处理程序处理太繁琐
优化:使用一个事件处理程序同时处理多个表单元素
多表单元素优化步骤:
class App extends React.Component {
// 简化语法
state = {
txt: '',
content: '',
city: 'bj',
isChecked: false
}
// 事件处理程序
handleForm = e => {
// 获取当前DOM对象
const target = e.target
// 根据类型获取值
const value = target.type === 'checkbox' ? target.checked : target.value
// 获取name
const name = target.name
this.setState({ // 这里的this指向下面箭头函数的this
[name]: value
})
}
render() {
return (
<div>
{/* 文本框 */}
<input type="text" name="txt" value={this.state.txt} onChange={this.handleForm} />
<br />
{/* 富文本框 */}
<textarea name="content" value={this.state.content} onChange={this.handleForm}></textarea>
<br />
{/* 下拉框 */}
<select name="city" value={this.state.city} onChange={this.handleForm}>
<option value="sh">上海</option>
<option value="bj">北京</option>
<option value="hz">杭州</option>
</select>
<br />
{/* 复选框 */}
<input type="checkbox" name="isChecked" checked={this.state.isChecked} onChange={this.handleForm} />
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
说明:借助于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 )
class App extends React.Component {
constructor() {
super()
// 创建ref
this.txtRef = React.createRef()
}
// 获取文本框的值
getTXT = () => {
console.log("文本框的值:", this.txtRef.current.value)
}
render() {
return (
<div>
<input type="text" ref={this.txtRef} />
<button onClick={this.getTXT}>获取文本框的值</button>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
需求:
setState()
setState()
方法更新stateclass Hello extends React.Component {
// 初始化状态
state = {
comments: [
/* { id: 1, name: 'jack', content: '沙发! ! !' },
{ id: 2, name: 'rose', content: '板凳' },*/
{ id: 3, name: 'tom', content: '楼主好人' }
],
// 评论人
userName: '',
// 评论内容
userContent: ''
}
// 渲染评论列表
renderList() {
const { comments } = this.state
if (comments.length === 0) {
return <div className="no-comment">暂无评论, 快去评论吧~</div>
}
return (
<ul> {
comments.map(
item => (
<li key={item.id}>
<h3>评论人: {item.name}</h3>
<p>评论内容: {item.content}</p>
</li>
)
)}
</ul>
)
}
// 处理表单元素值
handleForm = e => {
const { value, name } = e.target
this.setState({
[name]: value
})
}
// 发表评论的处理程序
addComments = () => {
const { comments, userName, userContent } = this.state
// console.log(userName, userContent)
//非空校验
if (userName.trim() === '' || userContent.trim() === '') {
alert('请输入评论人和评论内容')
return
}
const newComments = [{
id: Math.random,
name: userName,
content: userContent
}, ...comments]
// console.log(newComments)
//文本框的值如何清空? 要清空文本框只需要将其对应的state清空即可
this.setState({
comments: newComments,
userName: '',
userContent: ''
})
}
render() {
const { userName, userContent } = this.state
return (
<div>
<div className="app">
<div>
<input
className="user"
type="text"
placeholder="请输入评论"
value={userName}
name="userName"
onChange={this.handleForm}
/>
<br />
<textarea
className="content"
cols="30" rows="10"
placeholder="请输入评论内容"
value={userContent}
name="userContent"
onChange={this.handleForm}
/>
<br />
<button onClick={this.addComments}>发表评论</button>
</div>
{/* 通过条件渲染决定渲染什么评论 */}
{this.renderList()}
</div>
</div>
)
}
}
// 渲染组件
ReactDOM.render(<Hello />, document.getElementById('root'))