安装脚手架
npm i -g create-react-app
新建项目
create-react-app 你的项目名字
类组件
import React from "react"
class HelloWorld extends React.Component {
render() {
return (
<div>
HelloWorld1
</div>
)
}
}
export default HelloWorld
函数组件
function helloWorld() {
return (
<div>
helloWorld11
</div>
)
}
export default helloWorld
/**
react16.8之前函数式组件时是无状态的,自身实现不了计数器功能
react16.8之后react hooks改变了这一现状
*/
JSX
语法真心屌啊
给样式&&事件绑定
className
给样式
事件绑定与原生很像
import React, { Component } from 'react'
import './helloworld.css'
export default class HelloWorld extends Component {
render() {
return (
<div className='demo' onClick={()=> {this.helloWorld()}}>HelloWorld</div>
)
}
helloWorld() {
console.log('click helloworld')
}
}
label标签聚焦属性有更改
为了跟js
中的for
关键字做区别
<label htmlFor='input'>用户名</label>
<input id='input'></input>
变量
跟vue
不同的是,react
中{}里面可以放变量或者表达式
import React, { Component } from 'react'
import './helloworld.css'
export default class HelloWorld extends Component {
foo = 'xiamingyu'
render() {
return (
<div>
<div className='demo' onClick={()=> {this.helloWorld()}}>HelloWorld</div>
<label htmlFor='input'>用户名</label>
<input id='input'></input>
<span>{this.foo}</span>
</div>
)
}
helloWorld() {
console.log('click helloworld')
}
}
事件绑定(this大战)
import React, { Component } from 'react'
import './helloworld.css'
export default class HelloWorld extends Component {
foo = 'xiamingyu'
render() {
return (
<div>
<div className='demo' onClick={this.helloWorld}>HelloWorld</div>
<div className='demo' onClick={()=> {console.log(this)}}>HelloWorld1</div>
// 推荐写法
<div className='demo' onClick={()=> {this.helloWorld2()}}>HelloWorld2</div>
<label htmlFor='input'>用户名</label>
<input id='input'></input>
<span>{this.foo}</span>
</div>
)
}
helloWorld() {
console.log('click helloworld', this)
}
helloWorld1() {
console.log('click helloworld1', this)
}
helloWorld2() {
console.log('click helloworld2', this)
}
}
分析
·1.点击helloworld
触发helloworld
函数,但是要注意的是,helloword
函数是由div
进行驱动的,所以this
指向的肯定不是HelloWorld
实例。
2.因为是箭头函数,函数体内的this是没有的,继承了外部render
函数的this
所以指向的是实例
3.这个我的理解是onclick
事件绑定的函数是一个箭头函数,点击div
驱动的是一个箭头函数,而这个箭头函数里面的this
是没有的,也就是箭头函数里面的this
是指向这个实例,所以helloworld2
内部的this
指向的是实例
事件对象
react
中的事件没有绑定到具体的dom
上面,而是通过事件委托的方式绑定到了根节点上面,并且函数有一个默认的事件对象参数
<div className='demo' onClick={(evt)=> {this.helloWorld2(evt)}}>HelloWorld2</div>
helloWorld2(evt) {
console.log('click helloworld2', this)
console.log(evt)
}
获取DOM
第一步:
myRef = React.createRef()
第二步
<div onClick={(evt)=> {this.helloWorld2(evt)}} ref={this.myRef}>HelloWorld2</div>
第三步
helloWorld2(evt) {
console.log(this.myRef.current)
}
状态
目前理解: 同vue
中的data
,状态决定了视图的展现内容,也是数据驱动视图
状态统一放在state
里面,做到数据驱动视图,需要调用setState
方法
import React, { Component } from 'react'
import './helloworld.css'
export default class HelloWorld extends Component {
state= {
isCollect: false
}
render() {
return (
<div>
<div className='demo' onClick={() => {this.onCollect()}}>{this.state.isCollect?'取消收藏':'收藏'}</div>
</div>
)
}
onCollect() {
// 注意render函数是会重新渲染的
this.setState({
isCollect: !this.state.isCollect
})
}
}
注意拿最新的值要在回调函数里面去拿
onCollect() {
this.setState({
isCollect: !this.state.isCollect
}, () => {
console.log(this.state.isCollect)
})
}
DOM循环
import React, { Component } from 'react'
export default class HelloWorld extends Component {
state= {
isCollect: false,
list: [1, 2, 3]
}
render() {
return (
<div>
{
this.state.list.map((item, index) =>
<div key={index}>
{item}
</div>
)
}
</div>
)
}
}
增删数组
import React, { Component } from 'react';
export default class HelloWorld extends Component {
state = {
isCollect: false,
list: [1, 2, 3],
};
input = React.createRef();
render() {
return (
<div>
{this.state.list.map((item, index) => (
<div key={index}>
<span>{item}</span>
<button onClick={() => this.onDelete(index)}>删除</button>
</div>
))}
<input type="text" ref={this.input} />
<button
onClick={() => {
this.add();
}}
>
添加
</button>
</div>
);
}
// 要避免直接修改原状态
add() {
const newList = [...this.state.list];
newList.push(this.input.current.value);
this.setState({
list: newList,
});
}
onDelete(index) {
const newList = [...this.state.list];
newList.splice(index, 1);
this.setState({
list: newList,
});
}
}
注意: 要避免直接修改原状态
条件渲染
// 类似v-if
{ !this.state.list.length && <div>暂无数据</div> }
// 类似v-show
<div className={this.state.list.length?'hidden': ''}>暂无数据</div>
富文本
<span dangerouslySetInnerHTML={
{
__html: item
}
}></span>