1. 组件
react组件:函数式组件和api式组件(不常用)和类式组件
// 1.函数式组件
import { render } from 'react-dom'
function Header() {
return(
<div>
<span>LOGO</span>
<nav>
<a href="/">a</a>
<a href="/">a</a>
<a href="/">a</a>
<a href="/">a</a>
</nav>
</div>
)
// 也可以直接返回null
}
// console.log(Header())
render(
<Header/>,
document.getElementById('root'),
() => console.log('render run')
)
// 2.createClass创建组件
import React from 'react';
import ReactDom from "react-dom";
// console.log(React);//{..,..,createClass} v16+ 拿掉了 所以需要单独下载
var createReactClass = require('create-react-class'); //es5 api调用
var Header = createReactClass({
render: function() {
return (
<div>
<span>LOGO</span>
<nav>
<a href="#">首页</a>
<a href="#">首页</a>
<a href="#">首页</a>
<a href="#">首页</a>
</nav>
</div>
);
// return React.createElement('h1',{},`Hello, ${this.props.name}/${this.state.count}`)
}
});
ReactDom.render(
<Header/>,
document.querySelector('#root'),
()=>console.log('end')
);
// 3.类组件
// import React from 'react';
import {Component} from 'react';
// import ReactDom from "react-dom";
import {render} from "react-dom";
// var let const class function import
//类组件 定义
// class Header extends React.Component{
class Header extends Component{
//每一个组件都会重Component基类上继承props,state,refs,context
render(){
//业务
// return jsx|null //jsx~~要渲染 null不渲染
return (
<div>
<span>LOGO</span>
<nav>
<a href="#">首页</a>
<a href="#">首页2</a>
<a href="#">首页3</a>
<a href="#">首页4</a>
</nav>
</div>
)
}
show(){}
}
//调用
{/*<Header/>*/}
// console.log(new Header())
//渲染
render(
<Header/>,
document.querySelector('#root'),
()=>console.log('end')
);
//4.组件在定义时的嵌套
class App extends Component{
render(){
return (
<div>
<Header/>
<div>
<div>slider</div>
<div>content</div>
</div>
<Footer/>
</div>
)
}
}
class Header extends Component{
render(){
//业务
return (
<div>header</div>
)
}
}
class Footer extends Component{
render(){
//业务
return (
<div>footer</div>
)
}
}
render(
<App/>,
document.querySelector('#root'),
()=>console.log('end')
);
// 5.调用时_组件嵌套
class Left extends Component{
render(){
return(
<div>
<div>left</div>
{this.props.children} // jsx语法
</div>
)
}
}
class Title extends Component{
render(){
return(
<h3>标题</h3>
)
}
}
class App extends Component{
render(){
return(
<div>
<div>最外层</div>
<Left>
<Title/>
</Left>
</div>
)
}
}
render(
<App/>,
document.getElementById('root'),
() => console.log('render end')
)
2. props
1. 传递属性 <组件名 属性名=值 属性名2=值2 .. />
propName="字符" propName={js数据类型} 属性名的定义需遵循小驼峰命名
2. 使用属性
{this.props.属性名}
this 代表的是组件本身
对象无法直接通过{对象}展示 需要直接渲染里面的键
import {render} from "react-dom";
import {Component} from 'react'
//6.props 组件属性 || 构造参数 || 函数参数
class App extends Component{
// 每一个组件都会从Component基类上继承props,state,refs,context
render(){
// 组件传的参数直接解构出来
let {str,num,num1,arr,obj,bl,un,nu} = this.props
return(
<div>
<p>字符串:{str}</p>
<p>数字:{num}</p>
<p>数字1:{num1}</p>
{/*<p>对象:{obj}</p>*/}
<p>对象:{obj.a}----{obj.b}</p>
<p>数组:{arr}</p>
<p>布尔:{bl}</p> // 不展示
<p>undefined:{un}</p> // 不展示
<p>null:{nu}</p> // 不展示
</div>
)
}
}
render(
<App str="bmw" num={'10'} num1={10} arr={[1,'qq',false]} obj={{a:1,b:2}} bl={true} un={undefined} nu={null} />,
document.getElementById('root'),
() => console.log('end')
)
3.类型检查
import propsTypes from ‘prop-types’ // 需要下载第三方组件
//默认值:
组件.defaultProps={propName:值,xx:oo}
//类型约定:
组件.propTypes={propsName:propsTypes库.类型名,xx:类型}
//propsTypes库.array/bool/func/number/object/string
//必传参数
propName: propsTypes库.类型名.isRequired
组件无论是使用函数声明还是通过 class 声明,都决不要修改自身的 props
import {render} from "react-dom";
import {Component} from 'react'
import pro from 'prop-types'
class Person extends Component{
render(){
console.log(this)
let {age, name} = this.props;
return(
<div>
<p>年龄:{age}</p>
<p>姓名:{name}</p>
</div>
)
}
}
//设置props默认值
Person.defaultProps={
name:'哈哈哈哈'
};
//设置props类型
Person.propTypes = {
name:pro.string,
age:pro.number.isRequired
};
也可以将示例属性直接写在实力内
class Person extends Component{
static defaultProps={
name:'哈哈哈哈'
};
static propTypes = {
name:pro.string,
age:pro.number.isRequired
};
render(){
let {age, name} = this.props;
return(
<div>
<p>年龄:{age}</p>
<p>姓名:{name}</p>
</div>
)
}
}
render(
<Person name={'哈哈'} />,
document.getElementById('root'),
()=>console.log('render voer')
)
4.事件
- React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
- 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串
- 类组件,事件函数内部this会丢失
- 事件绑定
<JSX元素 onClick={this.实例方法|函数体} - 修正this
onClick={this.方法.bind(this,值)}
onClick={()=>this.方法()}
构造器: this.方法=this.方法.bind(this) √
实例方法=()=>{箭头函数定义方法} √√ 现在常用的方式 - 事件对象
实例方法(ev) ev 代理事件对象 ev.target 返回虚拟Vdom √ - 冒泡
阻止: ev.stopPropagation() - 默认行为
阻止: ev.preventDefault() - 传参
onClick={this.clickHandler2.bind(this, 12)}
onClick={()=>this.clickHandler2(12)}
// 事件_this指向_传参_冒泡_默认行为
import {render} from "react-dom";
import {Component} from 'react'
class Animal extends Component{
/**
* 改变this指向的方法
* onClick={this.方法.bind(this,值)}
onClick={()=>this.方法()}
构造器: this.方法=this.方法.bind(this) √
实例方法=()=>{箭头函数定义方法} √√
* @returns {*}
*/
constructor () {
super();
this.show5 = this.show5.bind(this)
}
render(){
return(
<div>
<button onClick={this.show1}>按钮1</button>
<button onClick={this.show2.bind(this)}>按钮2</button>
<button onClick={() => this.show3()}>按钮3</button>
<button onClick={this.show4}>按钮4</button>
<button onClick={this.show5}>按钮5</button>
<h3>事件对象</h3>
<button onClick={this.show6}>按钮6</button>
<h3>传参</h3>
{/*需要传参时可以使用bind方法进行传参 第一个参数随意 第二个参数是值*/}
<button onClick={this.show7.bind(null,12)}>按钮7</button>
{/*想直接使用函数的执行传参 需要在套一个函数 参数是事件对象 执行函数的传参需要传值和事件对象*/}
<button onClick={(ev)=>this.show7(13,ev)}>按钮7-2</button>
</div>
)
}
show1(){
console.log('show1',this)
}
show2(){
console.log('show2',this)
}
show3(){
console.log('show3',this)
}
show4 = () => {
console.log('show4',this)
}
show5(){
console.log('show5',this)
}
show6 = (ev) => {
console.log(ev,ev.target)
}
show7 = (arg,ev) => {
console.log(arg,ev.target)
}
}
render(
<Animal/>,
document.getElementById('root'),
() =>console.log('end')
);
5 状态
state|数据|私有状态|本地状态
1. 定义
//es6+
//实例属性: state
class App{state:{}}
//es6:构造器 this.state
class App extends React.Component{
constructor(){
this.state={}
}
}
//ES5:
createReactClass({
getInitialState:function(){
return {
状态名:值,xx:oo
}
}
})
2 获取
//渲染
{this.state.proname}
//获取
this.state.proname
3 修改状态
//修改
this.setState(对象) //浅合并state
this.setState((asyncState,prevProps)=>{
//一般是用于在setState之前做一些操作
//this.state==同步结果
//asyncState==异步结果
//this.props==后
//prevProps==前
return {
sname:value
}
})
this.setState({
sname:value
}, () => {
//一般是用于在setState之后做一些操作
//this.state == 修改之后的state
})
**setState的结果是异步的**
组件状态代码示例
import {render} from "react-dom";
import {Component} from 'react'
class Demo extends Component{
state = {
title:'哈哈哈',
count:0,
list:['红楼梦','三国演义','西游记','金瓶梅'],
}
render(){
let {title,list,count} =this.state
return(
<div>
<h1>{title}</h1>
<p>{list}</p>
<p>{count}</p>
<button onClick={this.setData}>修改数据</button>
<button onClick={this.changeCount}>修改数量</button>
</div>
)
}
setData = () => {
// console.log(this.state.title)
// this.state.title = '哈哈哈被修改'
// console.log(this.state.title)
this.setState({
title:'哈哈哈被修改成功'
})
}
changeCount = () => {
// this.setState({
// count:this.state.count+1
// })
this.setState({
count:this.state.count+1
}, () => {
console.log('异步',this.state.count)
})
console.log('同步',this.state.count)
}
}
render(
<Demo/>,
document.getElementById('root'),
() => console.log('end')
)