1.受控组件案例
1.1之前的影院案例改写
import React, { Component } from 'react'
import axios from 'axios'
import BetterScroll from 'better-scroll'
import './css/02_tab.css'export default class Cinema extends Component {constructor() {super();this.state = {cinemaList: [],mytext:''// backcinemaList: []}//react中使用axios第三方的库 专门用来请求数据// axios.get("请求地址").then(res=>{}).catch(err=>{console.log(err);})axios({url: "https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=7406159",method: 'get',headers: {'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.0.4","e":"16395416565231270166529","bc":"110100"}','X-Host': 'mall.film-ticket.cinema.list'}}).then(res => {console.log(res.data)this.setState({cinemaList: res.data.data.cinemas,// backcinemaList: res.data.data.cinemas})new BetterScroll(".wrapper")}).catch(err => console.log(err))}render() {return (<div><div>{/* <input onInput={this.handleInput}></input>实时搜索 */}<input value={this.state.mytext} onChange={(evt)=>{this.setState({mytext:evt.target.value},()=>{console.log(this.state.mytext);})}}></input>实时搜索</div><div className='wrapper' style={{height:'800px',overflow:'hidden'}}><div className='content'>{this.getCinemaList().map((item) =><dl key={item.cinemaId}><dt>{item.name}</dt><dd>{item.address}</dd></dl>)}</div></div></div>)}getCinemaList=()=>{//return this.state.cinemaListreturn this.state.cinemaList.filter(item => item.name.toUpperCase().includes(this.state.mytext.toUpperCase()) ||item.address.toUpperCase().includes(this.state.mytext.toUpperCase()))}// handleInput = (event) => {// console.log("input", event.target.value);// // 数组的filter方法不会影响原数组// var newList = this.state.backcinemaList.filter(item => item.name.toUpperCase().includes(event.target.value.toUpperCase()) ||// item.address.toUpperCase().includes(event.target.value.toUpperCase()))// this.setState({// cinemaList: newList// })// }
}
1.2 todolist改写
import React, { Component } from 'react'export default class App extends Component {constructor() {super();this.state = {addList: [{id: Math.random()*10000, title: "张三"}],mytext:''}}//myref = React.createRef();render() {return (<div><input value={this.state.mytext} onChange={(evt)=>{this.setState({mytext:evt.target.value})}}></input><button onClick={() => {this.handler()}}>增加</button><ul>{this.state.addList.map((item,index) =><li key={item.id}>{/* {item.id}----{item.title} */}<span dangerouslySetInnerHTML={{__html:item.id+"------"+item.title}}></span><button onClick={()=>{this.deleteList(index)}}>删除</button></li>)}</ul>{/* {this.state.addList.length===0 ?<div>暂无待办事项</div>:null} */}{this.state.addList.length===0 && <div>暂无待办事项</div>}</div>)}handler = () => {let newList = [...this.state.addList]newList.push({id: Math.random()*10000,title: this.state.mytext})this.setState({addList: newList,mytext:''}) }deleteList=(index)=>{console.log(index);let newList = [...this.state.addList];newList.splice(index,1);//从该下标开始删除 删除一个this.setState({addList: newList})}
}
2.父子通信
场景:比如我有一个父组件 父组件内部有1个导航组件 一个侧边栏组件 在导航栏组件中,我做了一个操作后,想让侧边栏组件隐藏与显示
这就需要子传父了 导航栏组件传递信号给父组件 父组件再去控制侧边栏组件
例如:
父组件:
通过state中的isShow来控制侧边栏组件的显示
import React, { Component } from 'react'
import Navbar from './compoent/Navbar'
import SideBar from './compoent/SideBar'export default class App extends Component {state={isShow:true,}render() {return (<div> <Navbar/>{this.state.isShow && <SideBar/>}</div>)}
}
侧边栏组件
import React, { Component } from 'react'export default class SideBar extends Component {render() {return (<div style={{background:"green",width:"300px"}}><ul><li>11111</li><li>11111</li><li>11111</li><li>11111</li><li>11111</li><li>11111</li><li>11111</li></ul></div>)}
}
导航栏组件
import React, { Component } from 'react'export default class Navbar extends Component {render() {return (<div style={{background:"yellow",width:"400px"}}><button>控制侧边栏</button></div>)}
}
现在需要去做修改,使用event属性传一个回调函数,然后子组件中调用此函数
可以发现子组件中点击按钮后,已经可以控制父组件中打印了。因此咱后面可以在父组件中修改state中的值了
export default class App extends Component {state={isShow:true,}render() {return (<div> <Navbar event={()=>{console.log("父组件中可以修改state了");this.setState({isShow:!this.state.isShow})}}/>{this.state.isShow && <SideBar/>}</div>)}
}
总结:
父传子:传属性
子传父:父给子一个函数,子执行此函数 当成回调函数
3.父子通信版:表单域组件
import React, { Component } from 'react'
import Field from './compoent/Field'export default class App extends Component {state={username:"",password:""}render() {return (<div><Field label="用户名" type="text" value={this.state.username} onChangeEvent={(value)=>{// console.log("value==="+value);this.setState({username:value})}}></Field><Field label="密码" type="password" value={this.state.password} onChangeEvent={(value)=>{// console.log("value==="+value);this.setState({password:value})}}></Field><button onClick={()=>{console.log(this.state.username+"\t"+this.state.password+"发送给后端校验");}}>登录</button><button onClick={()=>{this.setState({username:"",password:""})}}>重置</button></div>)}
}
import React, { Component } from 'react'export default class Field extends Component {render() {return (<div><label>{this.props.label}</label><input type={this.props.type} value={this.props.value} onChange={(evt)=>{// console.log(evt.target.value);this.props.onChangeEvent(evt.target.value);}}></input></div>)}
}
4.ref版:表单域组件
import React, { Component } from 'react'
import Field2 from './compoent/Field2'export default class App extends Component {username=React.createRef();password=React.createRef();render() {return (<div><Field2 label="用户名" type="text" ref={this.username}></Field2><Field2 label="密码" type="password" ref={this.password}></Field2><button onClick={()=>{console.log(this.username); //可以发现这里拿到的是Field2这个组件console.log(this.username.current.state.value+"\t"+this.password.current.state.value+"发送给后端校验");}}>登录</button><button onClick={()=>{this.username.current.clear();this.password.current.clear();}}>重置</button></div>)}
}
import React, { Component } from 'react'export default class Field2 extends Component {state={value:""}clear(){this.setState({value:""})}render() {return (<div><label>{this.props.label}</label><input type={this.props.type} value={this.state.value} onChange={(evt)=>{this.setState({value:evt.target.value})}}></input></div>)}
}
console.log(this.username); //可以发现这里拿到的是Field2这个组件
5.非父子通信方式
5.1 状态提升(中间人模式)
React中的状态提升概括来说,就是将多个组件需要共享的状态提升到它们最近的父组件上。在父组件上改变这个状态然后通过props分发给子组件。