一、对参数做限制
yarn add prop-types
- 在
class
中声明static propTypes
static propTypes = { method:PropTypes.func.isRequired }
二、解决跨域
如果只有一个服务器,直接在package.json中配置 "proxy":"http://localhost:4001" 然后在代码中使用时端口换成项目本地的端口
axios.get('http://localhost:3000/students').then((res)=>{
console.log(res);
},error=>{
console.log(error);
})
如果有多个代理:设置setupProxy.js
在src文件夹下新建setupProxy.js
,【名字不能变】
// 此时的高版本需要拿到原来低版本导出值的子属性 createProxyMiddleware
const proxy = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
proxy.createProxyMiddleware("/api", {
target: " http://localhost:4001", //
changeOrigin: true,
pathRewrite: {
"^/api": "",
},
})
);
};
代码中:
axios.get('/api/students').then((res)=>{
console.log(res);
},error=>{
console.log(error);
})
三、前端路由的工作原理
利用HTML5 的新 API,pushState 和 replaceState,做到改变浏览器地址却不刷新页面的效果
四、NavLink和Link
- NavLink可以实现路由链接的高亮,通过activeClassName指定样式
- 标签体内容是一个特殊的标签属性
- 通过this.props.children可以获取标签体内容
五、路由的严格匹配和模糊匹配
- 默认使用模糊匹配,顺序一致
- 开启严格匹配,【exact】
- 严格匹配在需要时再开启,有时会无法匹配到二级路由
六、路由传参
params
传参- 路由链接携带参数
link to='/home/detail/xch'
- 注册路由
Route path='/home/detail/:name'
- 接收参数:
const { id, title } = this.props.match.params
- 路由链接携带参数
search
传参- 路由链接携带参数
link to='/home/detail?name=xch&age=18'
- 注册路由【无需申明】
- 接收参数:
const { search } = this.props.location
- 路由链接携带参数
state
传参- 路由链接携带参数
link to={{path:'/home/detail', state:{name:'xch'}}}
- 注册路由【无需申明】
- 接收参数:
const { state } = this.props.location
- 路由链接携带参数
七、路由跳转push和replace
八、如何让一般组件使用路由组件上的方法?
withRoute
九、hooks
React16.8后推出的新特性,可以在函数式组件中使用state及其他React特性
常用的三个hooks
-
useState()
语法:const [xxx,setXXX] = React.useState(initValue)
说明:参数:第一次初始化的值在内部作缓存;返回值:包含2个元素的数组, 第一个为内部当前状态的值,第二个为更新状态值的函数function UseState() { const [num, setNum] = React.useState(0) let click = () => { // setNum(num+1) setNum(num=>num+1) } // function click() { // setNum(num+1) // } return ( <div> <h2>当前值为:{num}</h2> <button onClick={click}>按钮</button> </div> ) } export default UseState
-
useEffect()
可以在函数组件中模拟类组件中的生命周期函数 语法:
useEffect(()=>{ //在此可以执行任意操作 return ()=>{}//在组件卸载前调用,比如清除定时器、订阅发布 },[])
说明:可以将它看成是:
componentDidMount、componentDidUpdate、componentWillUnMount
三个生命周期函数的结合 -
useRef()
可以在函数组件中存储、查询组件内的标签和数据
语法:
const myRef = useRef()
作用:保存标签对象,作用和
React.createRef
一样 -
useCallback()和useMemo()
说明: 类似于类组件中的
shouldComponentUpdate
函数,当子组件的props 或 state 发生改变时子组件才会被调用,从而避免每次父组件render时都去重新渲染子组件。 useCallback + memo 避免组件不必要重的重复渲染 useMemo 避免组件在每次渲染时都进行高开销的计算 类似Vue中的computed函数 -
useLayoutEffect()
说明: 会在渲染的内容更新到DOM上之前执行,会阻塞DOM的更新,而useEffect是在内容更新到DOM后执行
十、Fiber
放弃了,涉及React源码的阅读,暂时不想看
十一、组件通信方式总结
1.props:
(1).children props
(2).render props
2.消息订阅-发布:
pubs-sub、event等等
3.集中式管理:
redux、dva等等
4.context:
生产者-消费者模式
context
context上下文
即上下文, 设置后在一定范围内, 后代组件可以调用根组件数据 一般不用,都用redux
- 全局创建一个context对象
const ThemeContext = React.createContext();
- 在根组件中使用context对象的Provider包裹
<Provider value={this.state.them}> <Toolbar /> </Provider>
- 在需要接受的组件中定义一个静态变量
static contextType = ThemeContext
使用时:{this.context}
,注意是【context】
十二、React-Redux和Redux【重点】
- actions中负责操作符(type)操作数据(data)
- reducer中负责对应的处理逻辑
- 将多个reducer通过combineReducers进行合并后和store进行关联
- 通过Provider控制整个项目,确保所有子组件拿到store
- 容器中通过connect定义出在ui组件中需要使用的字段和方法,容器中上方是UI,下方是connect
- 容器中使用时通过this.props对象获取 源码在本地React/redxdemo中