赞
踩
函数组件:使用JS的函数或者箭头函数创建的组件
大写字母开头
必须有返回值
,表示该组件的结构使用函数创建组件
function Hello () {
return (
<div>这是我的函数组件</div>
)
}
使用箭头函数创建组件
const Hello = () => <div>这是一个函数组件</div>
使用组件
ReactDOM.render(<Hello />, document.getElementById('root'))
例子:
01-函数组件-基本使用
import React from 'react' import ReactDOM from 'react-dom' /* 1. 通过函数创建一个组件即可 1. 组件的名字必须是大写开头 为了区分html原有的标签 2. 组件必须返回一段结构 3. 如果组件不想渲染任何的内容 也需要return null */ function Hello() { return <div>我是hello组件</div> } const element = ( <div> <h1>函数组件</h1> {/* 使用组件 */} <Hello></Hello> <Hello></Hello> </div> ) ReactDOM.render(element, document.getElementById('root'))
02-函数组件-箭头函数
import React from 'react'
import ReactDOM from 'react-dom'
const Hello = () =><div>我是Hello组件</div>
const element = (
<div>
<h1>函数组件</h1>
{/* 使用组件 */}
<Hello></Hello>
<Hello></Hello>
</div>
)
ReactDOM.render(element, document.getElementById('root'))
class 类名{}
constructor
的用法,创建对象/* class 类 extends 继承 */ // function Teacher(name, age) { // this.name = name // this.age = age // } // Teacher.prototype.sayHi = function () { // console.log('大家好,我是' + this.name) // } // const stu = new Teacher('松哥', 29) // console.log(stu) // stu.sayHi() // class是一个语法糖 class Teacher { // 构造函数 constructor(name, age) { this.name = name this.age = age } sayHi() { console.log('大家好,我是' + this.name) } sing() { console.log('能够唱歌') } } const stu = new Teacher('松哥', 29) console.log(stu) stu.sing()
/* Person 人 Chinese 中国人 African 非洲人 */ class Person { constructor(name, gender) { this.name = name this.gender = gender } eat() { console.log('都会吃') } } class Chinese extends Person { constructor(name, gender) { // 父类的构造函数 super(name, gender) this.skin = 'yellow' } pingpong() { console.log('打乒乓球') } } const c1 = new Chinese('姚明', 40) console.log(c1) c1.eat() c1.pingpong() class African extends Person { constructor(name, gender) { super(name, gender) this.skin = 'black' } run() { console.log('跑的贼快') } } const xh = new African('小黑', 30) console.log(xh)
项目中的组件多了之后,该如何组织这些组件呢?
实现方式
创建Hello.js
创建组件(函数 或 类)
在 Hello.js 中导出该组件
在 index.js 中导入 Hello 组件
渲染组件,
05-类组件的语法
import { Component } from 'react' import ReactDOM from 'react-dom' /* 1. 类组件必须继承React.Component 2. 必须提供render方法 3. render方法必须由返回值,需要返回一段结构 */ class Hello extends Component { render() { return <div>我是hello组件</div> } } const element = ( <div> <h1>类组件</h1> <Hello></Hello> <Hello></Hello> </div> ) ReactDOM.render(element, document.getElementById('root'))
06-把组件抽取到独立的js中
Demo
const Demo = () => <div>我是一个函数组件</div>
export default Demo
Hello
import { Component } from 'react'
class Hello extends Component {
render() {
return <div>我是一个Hello组件</div>
}
}
export default Hello
index
import ReactDOM from 'react-dom'
import Hello from './components/Hello.jsx'
import Demo from './components/Demo.jsx'
const element = (
<div>
<h1>类组件</h1>
<Hello></Hello>
<Demo></Demo>
</div>
)
ReactDOM.render(element, document.getElementById('root'))
比如计数器案例,点击按钮让数值+1, 0和1就是不同时刻的状态,当状态从0变成1之后,UI也要跟着发生变化。React想要实现这种功能,就需要使用有状态组件来完成。
state
即数据,是组件内部的私有数据
,只有在组件内部可以使用state的值是一个对象
,表示一个组件中可以有多个数据07-类组件提供状态
import { Component } from 'react' import ReactDOM from 'react-dom' /* 给类组件提供状态 */ class App extends Component { constructor() { super() // 给this增加一个属性 state this.state = { msg: 'hello', count: 0, } } render() { return ( <div> <h1>我是根组件</h1> <div>{this.state.msg}</div> <div>{this.state.count}</div> </div> ) } } ReactDOM.render(<App />, document.getElementById('root'))
09-类组件-提供状态简写
import { Component } from 'react' import ReactDOM from 'react-dom' /* 给类组件提供状态 */ class App extends Component { // constructor() { // super() // // 给this增加一个属性 state // this.state = { // msg: 'hello', // count: 0, // } // } state = { msg: 'hello', count: 0, } render() { return ( <div> <h1>我是根组件</h1> <div>{this.state.msg}</div> <div>{this.state.count}</div> <button>+1</button> </div> ) } } ReactDOM.render(<App />, document.getElementById('root'))
React注册事件与DOM的事件语法非常像
语法on+事件名={事件处理程序}
比如onClick={this.handleClick}
注意:React事件采用驼峰命名法,比如onMouseEnter
, onClick
class App extends React.Component {
render() {
return (
<div>
<button onClick={this.handleClick}>点我</button>
</div>
)
}
handleClick() {
console.log('点击事件触发了')
}
}
可以通过事件处理程序的参数获取到事件对象
function handleClick(e) {
e.preventDefault()
console.log('事件对象', e)
}
<a onClick={this.handleClick}>点我,不会跳转页面</a>
事件处理程序中的this指向的是undefined
render方法中的this指向的而是当前react组件。只有事件处理程序中的this有问题
class App extends React.Component {
state = {
msg: 'hello react'
}
handleClick() {
console.log(this.state.msg)
}
render() {
return (
<div>
<button onClick={this.handleClick}>点我</button>
</div>
)
}
}
例子:
10-类组件-注册事件的基本使用
import { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component { state = { count: 0, } render() { return ( <div> <h1>我是根组件</h1> <div>{this.state.count}</div> <button onClick={this.clickFn} onMouseEnter={this.mouseFn}> +1 </button> <a href="http://www.baidu.com" onClick={this.clickFn}> 百度一下 </a> </div> ) } clickFn(e) { //e.preventDefault()会阻止表单提交的时候 重新加载页面。 e.preventDefault() //e.stopPropagation()阻止事件冒泡。 e.stopPropagation() console.log('点击事件') } mouseFn() { console.log('鼠标进入事件') } } ReactDOM.render(<App />, document.getElementById('root'))
11-类组件-事件中的this问题
import { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component { state = { count: 0, } render() { console.log('render', this) return ( <div> <h1>我是根组件</h1> <div>{this.state.count}</div> <button onClick={this.clickFn}>+1</button> </div> ) } clickFn() { console.log(this) console.log('点击事件') console.log(this.state.count) } } ReactDOM.render(<App />, document.getElementById('root'))
箭头函数的特点:自身没有this,访问的是外部的this
方式1:
class App extends React.Component {
state = {
msg: 'hello react'
}
render() {
return (
<div>
<button onClick={() => { console.log(this.state.msg) }>点我</button>
</div>
)
}
}
缺点:会把大量的js处理逻辑放到JSX中,将来不容易维护
方式2
class App extends React.Component {
state = {
msg: 'hello react'
}
handleClick() {
console.log(this.state.msg)
}
render() {
return (
<div>
<button onClick={() => {this.handleClick()}}>点我</button>
</div>
)
}
}
缺点:把大量的js逻辑写在了JSX结构中,不好维护
class App extends React.Component {
state = {
msg: 'hello react'
}
handleClick() {
console.log(this.state.msg)
}
render() {
return (
<div>
<button onClick={this.handleClick.bind(this)}>点我</button>
</div>
)
}
}
或者
class App extends React.Component { constructor() { super() this.handleClick = this.handleClick.bind(this) } state = { msg: 'hello react' } handleClick() { console.log(this.state.msg) } render() { return ( <div> <button onClick={this.handleClick}>点我</button> </div> ) } }
class App extends React.Component { state = { msg: 'hello react' } handleClick = () => { console.log(this.state.msg) } render() { return ( <div> <button onClick={this.handleClick}>点我</button> </div> ) } }
注意:这个语法是试验性的语法,但是有babel的转义,所以没有任何问题
例子:
import { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component { state = { count: 0, } // 在类组件中render的this不会有问题,,,this就指向当前组件 // 解决react类组件中注册事件的this问题 // 1. 把函数调用包裹在箭头函数中 // 原本写法: onClick={this.clickFn} // 写法 onClick={() => this.clickFn()} // 2. 使用bind修改this的指向 // onClick={this.clickFn} // bind优化 onClick={this.clickFn.bind(this)} // 3. class新语法: 类实例语法 // onClick={this.clickFn} // 把方法写法修改一下 clickFn = () => { console.log(this) } render() { return ( <div> <h1>我是根组件</h1> <div>{this.state.count}</div> <button onClick={this.clickFn}>+1</button> </div> ) } clickFn = () => { console.log('123', this) } } ReactDOM.render(<App />, document.getElementById('root'))
组件中的状态是可变的
语法this.setState({要修改的数据})
注意:不要直接修改state中的值,必须通过this.setState()
方法进行修改
setState
的作用
思想:数据驱动视图
import { Component } from 'react' import ReactDOM from 'react-dom' /* 给类组件提供状态 */ class App extends Component { state = { count: 0, list: ['张三', '李四', '王五'], } render() { return ( <div> <h1>我是根组件</h1> <div>{this.state.count}</div> <ul> {this.state.list.map((item, index) => ( <li key={index}>{item}</li> ))} </ul> <button onClick={this.clickFn}>+1</button> <button onClick={this.add}>增加数据</button> </div> ) } /* vue: vue会通过es5的语法Object.defineProperty() vue3.0 会通过es6的proxy语法 监测到数据的改变,,,当数据改变的时候,vue会帮助我们自动更新DOM 使用vue的时候,只需要直接修改数据即可。 react: react并不会去监听数据的变化,,,所以直接修改数据,react不知道。DOM就不会自动更新。 react提供了一个方法,,,setState 这个方法有两个作用:1.修改state的值 2. 更新DOM 结论: 1. react中不能直接修改state中的数据 2. react中必须使用setState去修改数据。 */ clickFn = () => { // console.log(this.state.count) // this.state.count++ // console.log(this.state.count) this.setState({ count: this.state.count + 1, }) } add = () => { this.setState({ list: [...this.state.list, '赵六'], }) } } ReactDOM.render(<App />, document.getElementById('root'))
我们在开发过程中,经常需要操作表单元素,比如获取表单的值或者是设置表单的值。
react中处理表单元素有两种方式:
HTML中表单元素是可输入的,即表单用户并维护着自己的可变状态(value)。
但是在react中,可变状态通常是保存在state中的,并且要求状态只能通过setState
进行修改。
React中将state中的数据与表单元素的value值绑定到了一起,由state的值来控制表单元素的值
受控组件:value值受到了react控制的表单元素
class App extends React.Component { state = { msg: 'hello react' } handleChange = (e) => { this.setState({ msg: e.target.value }) } render() { return ( <div> <input type="text" value={this.state.msg} onChange={this.handleChange}/> </div> ) } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。