文章目录
一、toDoList相关知识点
-
拆分组件,实现静态组件 注意:className style
-
动态初始化列表 如何确定将数据放在哪个组件的state中
--某个组件使用:放在其自身的state中 --某些组件使用:放在他们共同的父组件state中(官方称为:状态提升)
-
关于父子之间通信:
--[父组件]给[子组件]传值:通过props --[子组件]给[父组件]传值:父组件给子组件传一个函数 子组件通过函数将值传给父组件
-
注意defaultChecked 和checked的区别,类似的defaulValue和value
-
状态(数据)在哪里,操作状态的方法就在哪里
二、配置代理
1.设置proxy
在package.json文件里设置proxy,
2. 在setupProxy.js文件中设置
新建setupProxy文件,可以配置多个代理
代码如下:
const proxy = require('http-proxy-middleware')
module.exports = function(app){
app.use(
proxy('/api1',{
target:'http://localhost:5000',
changeOrigin:true,
pathRewrite:{'^/api1':''}
}),
proxy('/api2',{
target:'http://localhost:5001',
changeOrigin:true,
pathRewrite:{'^/api2':''}
})
)
}
三. 发布订阅实现兄弟通信
1. 几种通信方式:
-
props:
(1).children props (2).render props
-
消息订阅-发布:pubs-sub、event等等
-
集中式管理:redux、dva等等
-
conText: 生产者-消费者模式
2. 发布订阅插件
导入pubsub
import PubSub from 'pubsub-js'
PubSub.publish用来发布消息,第一个参数是事件名字,第二个参数是要传递的数据
PubSub.publish('update',{isFirst:false,isLoading:true})
PubSub.subscribe用来订阅消息,第一个参数是事件名称,第二个参数是回调函数,函数接收两个参数,第一个_,第二个是需要传递的数据.
componentDidMount() {
// 开启定时器 发布订阅
this.token = PubSub.subscribe('update',(_,stateObj)=>{
this.setState(stateObj)
})
}
componentWillUnmount() {
PubSub.unsubscribe(this.token)
}
四. Fetch发送请求
代码如下:
async function (){
try{
const response =await fetch(`/api1/search/users?q=${value}`)
const data = await response.json()
PubSub.publish('update',{isLoading:false,users:data.items})
}catch (e) {
PubSub.publish('update',{isLoading:false,err:e.message})
console.log('出错了',e)
}
}
五. 路由的基本使用
- 插件:react-router-dom
react-router-dom 的内置组件: <BrowserRouter>. <HashRouter> <Route>. <Redirect>. <Link>. <NavLink>. <Switch>
- 向路由组件传递参数
1.params参数
路由链接(携带参数):<link to='demo/test/tom/18'>详情</link>
注册路由(声明接收):<Route path='/demo/test/:name/:age' component={Test}></Route>
接收参数: const { } = this.props.match.params(旧)
使用hooks:
import { useParams } from "react-router-dom";
const params = useParams() //在组件函数里直接调用钩子函数拿值
{params.keywords}
2. search参数
路由链接(携带参数):<link to='demo/test?name=tom&age=18'>详情</link>
注册路由(无需申明,正常注册即可):<Route path='/demo/test' component={Test}></Route>
接收参数:this.props.location.search
备注:获取到的search是urlencoded编码字符串,需要借助querystring解析
代码如下:
import qs from 'querystring' //首先导入包
const {search} = this.props.location
const {id,title}= qs.parse(search.slice(1))
3. state参数
路由链接(携带参数):<link to={{path:'/demo/test',state:{name:'tom',age:18}}}>详情</link>
注册路由(无需申明,正常注册即可):<Route path='/demo/test' component={Test}></Route>
接收参数:const { } = this.props.location.state
备注:刷新也可以保留住参数 不想让参数显示在地址栏的情况课使用此方法
- 编程式路由导航
路由有push 与 replace两种模式 ,默认是push 模式.
开启replace模式(设置replace为true):
<Link replace={true} to={{pathname:'/home/message/detail',state:{id:msgObj.id,title:msgObj.title}}}>{msgObj.title}</Link>
link 和navlink 可以实现跳转,如果需要自己规定跳转方式实现点击跳转可使用编程式路由导航.借助this.props.history对象上的API对操作路由跳转,前进,后退.
this.props.history.push()
this.props.history.replace()
this.props.history.goBack()
this.props.history.goForward()
this.props.history.go()
代码如下:
<button onClick={()=>this.pushShow(msgObj.id,msgObj.title)}>push</button>
<button onClick={()=>this.replaceShow(msgObj.id,msgObj.title)}>replace</button>
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})
}
pushShow=()=>{
//push +params传参
this.props.history.push(`/home/message/detail/${id}/${title}`)
// push +search传参
// this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)
// push +state传参
// this.props.history.push(`/home/message/detail`,{id,title})
}
- withRouter
withRouter可以加工一般组件,让一般组件具备路由组件所特有的API .withRouter的返回值是一个新组件
代码如下:
export default withRouter(Header);
在react-router v6 新版本中不支持withRouter ,新使用useNavigate
import { useNavigate } from 'react-router-dom'
function anonyCom(MessCom) {
return (props) => {
let navigate = useNavigate();
return <MessCom {...props} navigate={navigate} />
}
}
export default anonyCom(Searchinput(需要被路由包裹的组件名))
当需要路由跳转时,不再使用props.history.push,而是使用props.navigate
props.navigate('/search/' + keywords)
- BrowserRouter和HashRouter的区别
1.低层原理不一样:
BrowserRouter使用的是H5的history API ,不兼容IE9以下版本.
HashRouter使用的是URL的哈希值.
2. url 表现形式不一样
BrowserRouter的路径中没有#
HashRouter的路径包含#
3. 刷新后对路由state参数的影响
BrowserRouter没有任何影响,因为state保存在history对象中.
HashRouter刷新后会导致state参数的丢失
4.备注:HashRouter可以用于解决一些路径错误相关的问题.
该处使用的url网络请求的数据。
总结
提示:这里对文章进行总结: