redux开发者工具的使用
代码语言:javascript复制import {composeWithDevTools} from 'redux-devtools-extension'
import { createStore, applyMiddleware, combineReducers } from 'redux'
import countReducer from './reducers/count'
import personReducer from './reducers/person'
// 用于支持异步action
import thunk from 'react-thunk'
// 汇总所有的reducer变为一个总的reducer
const allReducer = combineReducers({
he:countReducer,
rens:personReducer
})
// 没有异步action可以直接将 composeWithDevTools放入第二个参数
// 有异步action需要将 异步action放入 composeWithDevTools
export default createStore(allReducer, composeWithDevTools(applyMiddleware(thunk)))
setState 扩展
setSate异步更新 setState第二个参数接收一个回调函数,当状态更新完毕且界面更新完毕后 调用该函数
路由懒加载
代码语言:javascript复制import React, { Component, lazy, Suspense } from 'react'
const Home = lazy(() => import ('./Home'))
const About = lazy(() => import ('./About'))
2.将所有路由组件通过Suspense组件包裹 fallback接收一个组件,用于在路由切换时填充白屏效果
代码语言:javascript复制<Suspense fallback={<h1>加载中...</h1>}>
<Route path="/about" component={About}>
<Route path="/home" component={Home}>
</Suspense>
Hooks
使得函数组件中使用state 以及其他react的特性 1.函数组件使用state,
代码语言:javascript复制function Demo() {
// 返回一个数组,第一个为状态值,第二个为更新状态函数
// 第一次Demo调用count会被存储,第二次调用Demo count不会重置
const [count, setCount] = React.useState(0)
function add() {
// setCount(count 1) // 第一种
setCount(count => count 1)
}
}
2.生命周期钩子
代码语言:javascript复制React.useEffect(()=>{
},[]) // == didMount
React.useEffect(()=>{
},[count]) // == didUpdate
React.useEffect(()=>{
// 返回的函数相当于 willUnmount
return () => {
}
},[count]) // == didUpdate
// 相当于didMount和didUpdate、willUnmount
3.Ref hook
代码语言:javascript复制const myRef = React.useRef()
4.Fragment
代码语言:javascript复制<Fragment>解决元素层级过多问题
5.Context 一种组件通信方式,常用于【祖组件】于【后代组件】通信
代码语言:javascript复制// 创建 Context对象
const MyContext = React.createContext();
const { Provider,Consumer } = MyContext;
export default class A extends Component {
state = { username:'tzg' }
const username = this.state
render () {
return (
<div>
<span>A组件。。。。</span>
<Provider value={username}>
// B组件
<B/>
</Provider>
</div>
)
}
}
export default class C extends Component {
//
const contextType = MyContext
render () {
return (
// 访问A组件的数据
// 这种方式只能在类似组件使用
<div>{this.context}</div>
)
}
}
// 函数组件使用
function C() {
return (
<div>
<Consumer>
{
value => {
return ${value}
}
}
</Consumer>
</div>
)
}
组件优化问题
1.只要直销setState即使不改变状态数据,组件也会重新render()
2.只当前组件重新render(),就会自动更新render子组件,即使子组件没有用到父组件的数据 == 效率低下
原因
组件的shouldComponentUpdate总是返回true
解决
shouldComponentUpdate 判断处理
代码语言:javascript复制shouldComponentUpdate(nextProps, nextState) {
if (this.state.carName === nextState) {
return false
}else {
return true
}
}
解决
PureComponent PureComponent可以解决上述问题
PureComponent只是在shouldComponentUpdate进行了一些处理,比较 PureComponent只进行了浅对比
renderProps
类似vue插槽
代码语言:javascript复制export default class Parent extends Component {
render () {
return (
<div>
<h3>Parent组件</h3>
<A render={ name => <C name={name}/> }>
</div>
)
}
}
class A extends Component {
state = { name:'tom' }
render () {
const { name} = this.state
return (
<div>
<h3>A组件</h3>
{ this.props.render(name) }
</div>
)
}
}
错误边界
将错误控制在一定的范围之内 react中的组件错误边界始终去找父组件进行处理 只能捕获生命周期产生的错误
代码语言:javascript复制export default class Parent extends Component {
state = {
hasError:'' // 标识子组件是否产生错误
}
// 当组件出行报错时触发该钩子,并携带错误信息
static getDerivedStateFromError(error) {
return { hasError:error }
}
// 组件渲染 时出错 调用该钩子
componentDidCatch() {
console.log("记录日志发送给后台")
}
render () {
return (
<div>
{this.state.hasError ? '网络不稳定,等会在来':<Child />}
</div>
)
}
}
只适用于生产环境!
组件通信方式总结
1.props
2.消息订阅-发布
pubs-sub,event
3.集中式管理
redux,dva
4.context:生产者-消费者