一、消息订阅-发布机制
1、工具库:PubSubJS
2、下载:npm i pubsub-js --save
3、使用:
import PubSub from 'pubsub-js';//引入
PubSub.subscribe('delete',function(data){});//订阅
PubSub.publish('delete',data);//发布消息
二、连续解构赋值
let obj = {a:{b:{c:1}}};
let obj2= {a:{b:1}};
console.log(obj.a.b.c);
const {a:{b:{c}}} = obj;
//连续解构赋值
console.log(c);
//连续解构赋值加上重命名
const {a:{b:data}} = obj2;
console.log(data)
三、基于react搜索小案例
发布—订阅:
1、List什么时候订阅消息合适?
在页面渲染完成时进行订阅
import PubSub from 'pubsub-js';
componentDidMount(){
//第一个参数订阅的名称,第二个参数回调函数
this.token = PubSub.subscribe('atguigu',(_,stateObj)=>{
this.setState(stateObj)
})}
//组件卸载的时候,将订阅消息取消掉
componentWillUnmount(){
PubSub.unsubscribe(this.token)
}
2、Header代码
import PubSub from 'pubsub-js';
search = ()=>{
//第一个参数发布的名称,第二个参数为:所要传递的数据
PubSub.publish('atguigu',{isFirst:false})
}
四、ajax请求方式?
1、xhr最原始的方式
2、jQuery是对xhr的封装
3、axios是对xhr的封装
4、fetch是window内置
五、fetch
1、特点:
原生函数,不在使用XmlHttpRequest对象提交ajax请求
老版本浏览器可能不支持
2、代码片段:
(1)优化版本:
//发送网络请求,使用fetch方法
fetch('发送的地址').then(res=>{
//res.json()返回的是Promise实例对象
console.log('联系服务器成功了',res.json());
return res.json()
},err=>{
console.log('联系服务器失败了');
return new Promise(()=>{})
}).then(res=>{
console.log('获取数据成功了',res)
},err=>{
console.log('获取数据失败了',err)
})
(2)优化版本:
//发送网络请求,使用fetch方法
fetch('发送的地址').then(res=>{
console.log('联系服务器成功了',res.json());
return res.json()
}).then(res=>{
console.log('获取数据成功了',res)
}).catch(
(err) =>{
console.log(err)
}
)
(3)优化版本:
//发送网络请求,使用fetch方法
try{
const response = await fetch('发送的地址');
const data = await response.json();
console.log(data);
}catch(error){
console.log('请求出错',error)
}
六、基于react搜索小案例相关知识点
1、设计状态时要考虑全面,例如带有网络请求的组件,要考虑请求失败怎么办?
2、ES6小知识点:解构赋值+重命名
3、消息订阅与发布:
(1)先订阅,在发布(理解:有一种隔空对话的感觉)
(2)适用于任意组件间通信
(3)要在组件的componentWillUnmount中取消订阅
4、fetch发送请求(关注分离的设计思想)
try{
const response = await fetch('发送的地址');
const data = await response.json();
console.log(data);
}catch(error){
console.log('请求出错',error)
}
七、路由的基本使用
1、明确好界面中的导航区域、展示区
2、导航区a标签进行路径切换
<Link to='/xxxx'>Demo</Link>
3、展示区写Route标签进行路径的匹配
<Route path='/xxxx' component={Demo}></Route>
4、App的最外侧包裹了一个BroserRouter 或HashRouter
八、路由组件与一般组件
1、路由注册
<Route path='/about' component={About}></Route>
<Route path='/home' component={Home}></Route>
2、在React中靠路由链接实现切换组件–编写路由链接
<Link to='/about'></Link>
3、路由组件和一般组件最大的区别是:可以收到传递过来的props,这里面需要关注的有:
history/location/match
4、写法不同
一般组件
<Home/>
路由组件
<Route path='/home' component={Home}></Route>
5、存放位置不同
一般组件:components
路由组件:pages
6、接收到的props不同
一般组件:写组件标签时传递了什么,就能收到什么
路由组件:接收到三个固定的属性history/location/match
history:
go();
gouBack();
goForward();
push();
repalce();
location:
pathname:'/about'
search:''
state:undefined
match:
params:{};
path:'/about';
url:'/about'
7、想要高亮的效果,则需要将Link修改为NavLink:
<NavLink activeClassName="active" to='/about'>About</NavLink>
<NavLink activeClassName="active" to='/home'>Home</NavLink>
九、NavLink与封装NavLink
1、NavLink可以实现路由链家的高亮,通过activeClassName指定样式名
2、标签体内容是一个特殊的标签属性
3、通过this.props.children可以获取标签体内容
十、Switch组件
1、在注册多个路由的时候,使用Switch组件进行包裹,可以达到只要匹配到组件,即停止;
<Switch>
<Route path='/about' component={About}></Route>
<Route path='/home' component={Home}></Route>
</Switch>
2、通常情况下,path和component是一对一的关系
3、Switch可以提高路由匹配效率(单一匹配)
十一、解决多级路径页面样式丢失问题
1、将引入样式中的点去掉即可publilc/index.html
<link href='/css/bootstrap.css'>
2、书写的是绝对路径,由于是绝对类路径,所以一定不会出现问题
<link href='%PUBLIC_URL%/css/bootstrap.css'>publilc/index.htm
3、在不改变点的情况下
将<BrowserRouter>改为<HashRouter>
十二、路由的严格匹配和模糊匹配
1、模糊匹配
<MyNavLink to='/home/a/b'></MyNavLink>
<Route path='/home'></Route>
默认使用的是模糊匹配(简单记:【输入的路径】需要包含要【匹配的路径】,且顺序要一致);
2、严格匹配
<MyNavLink exact={true} to='/home/a/b'></MyNavLink>
<Route path='/home' exact={true}></Route>
3、严格匹配不要随便开启,需要在开,有些时候开启会导致无法继续匹配二级路由
十三、Redirect的使用
一般写在所有路由注册的最下方,当所有的路由都无法匹配的时候,跳转到Redirect指定的路由
<Switch>
<Route path='/about' component={About}></Route>
<Route path='/home' component={Home}></Route>
<Redirect to='/home'/>
</Switch>
十四、嵌套路由
注册子路由时写上父路由的path值
路由的匹配是按照注册路由顺序进行
十五、向路由组件传递params数据
1、携带params参数
<Link to={`/home/message/detail/${item.id}/${item.title}`}>{item.title}</Link>
2、声明接收params参数
<Route path='/home/message/detail/:id/:title' component={Deatil}></Route>
3、在子组件利用:this.props.match.params可以拿到具体值
路由链接(携带参数):<Link to={"/demo/test/tom/18"}>详情</Link>
注册路由(声明接收):<Route path='/demo/test/:name/:age' component={Test} />
接收参数:const {id,title} = this.props.match.params;
十六、search参数
<Link to={`/home/message/detail/?id=${item.id}&title=${item.title}`}>{item.title}</Link>
1、search参数无需声明接收,正常注册路由即可
<Route path='/home/message/detail' component={Deatil}></Route>
2、接收search参数
import qs from ’querystring’
let obj = {name:'tom',age:18} // name=tom&age = 18;urlencode编码形式
let str = 'carName = 奔驰&price = 199';
const {search} = this.props.location;
const result = qs.parse(search.slice(1)) //将前面的问号截取掉
备注:获取到的search是urlencode编码字符串,需要借助querystring解析
十七、state参数
// 向路由组件传递state参数
<Link to={{pathname:'/home/message/detail',state:{id:item.id,title:item.title}}}>{item.title}</Link>
// state参数无需声明接收,正常注册路由即可
<Route path='/home/message/detail' component={Deatil}></Route>
// 接收state参数
const {id,title} = this.props.location.state
备注:刷新也可以保留住参数
十八、push和repalce模式
十九、编程式路由导航
借助this.props.history对象上的API对操作路由跳转、前进、后退
this.props.history.push();
this.props.history.replace();
this.props.history.goBack();
this.props.history.goForward();
this.props.history.go();
replaceShow = (id,title) =>{
// replace跳转+携带params参数
this.props.history.replace('/home/message/detail/${id}/${title}')
// replace跳转+携带search参数
this.props.history.replace('/home/message/detail?id=${id}$title = ${title}')
// replace跳转+携带state参数
this.props.history.replace(`/home/message/detail`,{id,title})
}
<Button onClick={()=>{this.replaceShow(id,title)}}></Button>
pushShow = (id,title) =>{
//push跳转+携带params参数
this.props.history.push('/home/message/detail/${id}/${title}')
}
<Button onClick={()=>{this.pushShow(id,title)}}></Button>
二十、withRouter的使用
可以加工一般组件,让一般组件具备路由组件所特有的API,返回值是一个新组件
import { withRouter} from 'react-router-dom'
export default withRouter(Header)