import React,{Component} from 'react'
import ReactDOM from 'react-dom'
事件绑定
export default class App extends Component{
render(){
return(
<div>
<input ref="text1">
<button onClick={()=>{
console.log('简单逻辑推荐写法')
}}>
add
</button>
<button onClick={()=>this.btnclick()}>
add1
</button>
<button onClick={ this.btnclick2 }>
add2
</button>
</div>
)
}
btnclick(){
console.log('推荐此写法便于传参')
}
btnclick2 = ()=>{
console.log('比较推荐')
}
}
ref取值
export default class App extends Component{
render(){
return(
<div>
<input ref="text1">
<button onClick={()=>{
console.log(this.refs.text1.value) //这种即将被弃用 严格模式会报错
}}>
add1
</button>
</div>
)
}
}
// React认可方式:
export default class App extends Component{
myref = React.createRef()
render(){
return(
<div>
<input ref={this.myref}>
<button onClick={()=>{
console.log(this.myref.current.value) //推荐这种方式
}}>
add1
</button>
</div>
)
}
}
state状态
export default class App extends Component{
state = {
msg:'文字',
show:true
}
//第二种定义state方式 二选一即可
constructor(){ // 构造器
super() //必须 继承
this.state={
msg:'确认',
show:true
}
}
render(){
return(
<div>
<button onClick={()=>{
this.setState({ //修改state的唯一方式setState
show: !this.state.show
msg: 'wenzi'
})
if(this.state.show){
console.log('点击确认的逻辑')
}else{
console.log('点击取消的逻辑')
}
}}>
{this.state.show?'确认':'取消'}
</button>
</div>
)
}
}
循环渲染
export default class App extends Component{
state={
list=['11','22','33']
}
const newlist = this.state.list.map(i=><li key={i.id}>{i}</li>)
render(){
return(
<div>
<ul>
{ newlist }
</ul>
</div>
)
}
}
条件渲染小tip
//三元表达式
判断条件? 逻辑1 : 逻辑2
//若 逻辑2为 null 时 三元表达式可替换为
判断条件 && 逻辑1
setState更新问题
export default class App extends Component{
state={
list=[]
}
render(){
return(
<div>
<button onClick={()=>this.btnclick()}>btn</button>
<ul>
{
this.state.list.map(i=>
<li key='i.id'>{i}</li>
)
}
</ul>
</div>
)
}
btnclick(){
var arr = [1,2,3]
this.setState({
list:arr
},()=>{
console.log(this.state.list)
//此处会返回更新后的数据 即[1,2,3],且dom也将更新
})
console.log(this.state.list)
//此处不会返回更新后的数据 即[] 同步环境不会立即获取到值
//或者 在异步环境中更新setState,会立即拿到数据
settimeout(()=>{
this.setState({
list:arr
})
console.log(this.state.list)
//此处会返回更新后的数据 即[1,2,3],且dom也将更新
},0)
}
}
props传值、接收时的属性验证、属性默认值
//父组件
import Nav from './Nav'
export default class App extends Component{
state = {
msg:'文本'
}
render(){
return(
<div>
<Nav title="导航" ishow={true} />
<hr>
<Nav title={this.state.msg} ishow={false}/>
</div>
)
}
}
//Nav组件
export default class Nav extends Component{
let {title,ishow} = this.props //解构
// 类属性放入类组件中需要加 static
//接收值类型验证
static propTypes ={
title:PropTypes.string,
ishow:PropTypes.bool
}
//默认值
static defaultProps = {
ishow:true
}
render(){
return(
<div>
{ishow && <button>按钮</button>}
nav - {title} //解构后使用
nav - {this.props.title} //不解构直接使用
</div>
)
}
}
//子组件接收props属性验证
//需要 import PropTypes from 'prop-types' 可以打印PropTypes查看内含的方法
//对象属性可以直接 new 对象(). 访问 类属性放入类组件中 需要加 static 再进行使用
Nav.propTypes = { //不推荐此写法
title:PropTypes.string,
ishow:PropTypes.bool
}
函数式组件
export default function App(props){
console.log(props) // props 形参 自定义名字
return(
<div>
<span>{props.msg}</span>
</div>
)
}
//函数式组件 设置属性只能这样写
//App.defaultProps 设置默认属性
APP.propTypes = { //属性验证
title:PropTypes.string,
ishow:PropTypes.bool
}
模糊搜索filter
btnclcik = (event)=>{
//filter会返回一个新数组且不改变原数组
//这里建议传入copy后的数组
let filterlist = this.state.arrlist.filter(i=>{
i.name.toUpperCase().includes(event.target.value.toUpperCase())})
//字符串方法
this.state({
arrlist:filterlist
})
//这里会有错误,因为每次修改之后 会改变原数组,所以此处其实是做了叠加搜索 解决方式为 copy一个原数组 过滤时传入copy的数组
}