1 => 16.8 的context主要的目的是为跨越多个层级的组件提供数据的共享
import React, {Component, createContext} from 'react';
import logo from './logo.svg';
import './App.css';
const CountNumContext = createContext()
const CountStateContext = createContext()
class DetailPart extends Component{
render() {
return (
<CountNumContext.Consumer>
{
countNum =>
{
return (
<CountStateContext.Consumer>
{
countState => <h1>countNum: {countNum}, countState: {String(countState)}</h1>
}
</CountStateContext.Consumer>
)
}
}
</CountNumContext.Consumer>
)
}
}
class ChildPart extends Component{
render() {
return (
<DetailPart/>
)
}
}
class App extends Component {
state = {
countNum: 1,
countState: false
}
render() {
const {countNum, countState} = this.state
return (
<CountNumContext.Provider value={countNum}>
<CountStateContext.Provider value={countState}>
<button onClick={() => {this.setState({countNum: countNum + 1 })}}>addNum</button>
<button onClick={() => {this.setState({countState: !countState})}}>switchState</button>
<ChildPart></ChildPart>
</CountStateContext.Provider>
</CountNumContext.Provider>
)
}
}
export default App;
以上写法也可以通过contextType的方式省略consumer
import React, {Component, createContext} from 'react';
const CountContext = createContext()
class DetailPart extends Component{
static contextType = CountContext
render() {
const count = this.context
return (
<h1>countNum: {count.countNum}, countState: {String(count.countState)}</h1>
)
}
}
class ChildPart extends Component{
render() {
return (
<DetailPart/>
)
}
}
class App extends Component {
state = {
countNum: 1,
countState: false
}
render() {
const {countNum, countState} = this.state
return (
<CountContext.Provider value={this.state}>
<button onClick={() => {this.setState({countNum: countNum + 1 })}}>addNum</button>
<button onClick={() => {this.setState({countState: !countState})}}>switchState</button>
<ChildPart></ChildPart>
</CountContext.Provider>
)
}
}
export default App;
2 => lazy和Suspense配合优化性能
import React, {Component, lazy, Suspense} from 'react';
const TestLazy = lazy(() => import(/* webpackChunkName: "testLazy" */'./components/TestLazy.jsx'))
class App extends Component {
render() {
return (
<div>
<Suspense fallback={<div>loading</div>}>
<TestLazy/>
</Suspense>
</div>
)
}
}
export default App;
3 memo => 类组件的PureComponent相比component,区别在于shouldComponentUpdate, 前者等于自己封进行了装装,但无法识别对象中的对象。而memo则是赋予函数组件相同的PureComponent
const Foo = memo(function Foo(props) {
return (
<div>{props.person.age}</div>
)
})
4 useEffect=> useEffect(() => {} , []) , useEffect的执行时机主要取决于第二个参数。(无论哪种情况,初始都会执行一遍)
情况 1,如果没有第二个参数,则每次改变当前函数的state,和初始执行,都会接受回调
情况 2,如果第二个参数传入的数组变量是state中定义的某个变量,则会当改变这个变量的时候,执行传入useEffect的第一个函数
情况 3,如果第二个参数是空数组,则在初始执行useEffect传入的第1个函数。在销毁组件时执行useEffect第一个参数返回的函数
import React, {useEffect, useState} from 'react';
function App() {
const [count, setCount] = useState(0)
const [size, setSize] = useState({
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight
})
const onResize = () => {
setSize({
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight
})
}
useEffect(() => {
console.log('--情况1--')
})
useEffect(() => {
console.log('--情况2--')
//当count改变时执行
console.log('count:', count)
}, ['count'])
useEffect(() => {
console.log('--情况3--')
//组件初始执行
window.addEventListener('resize', onResize, false)
return () => {
//组件结束执行
window.removeEventListener('resize', onResize, false)
}
}, [])
return (
<div>
<button onClick={() => setCount(count+1)}>{count}</button>
<p>width: {size.width}, Height: {size.height}</p>
</div>
)
}
export default App;
5 useMemo,useCallback => 这两个函数大同小异,用法类似都可以作为回调函数传递给子组件
import React, {memo, useState, useMemo, useCallback} from 'react';
const Counter = memo(function (props) {
console.log('--momoCounterRendered--')
return (
<div onClick={props.onClick}>consoleCount</div>
)
})
function App() {
const [count, setCount] = useState(0)
const onClick1 = useMemo(() => {
return () => (
console.log('fetching:'+ count)
)
},[])
const onClick = useCallback(() => {
console.log(count)
setCount((count) => {
return count + 1
})
}, [count])
return (
<div>
<button onClick={() => {setCount(count + 1)}}>addCount{count}</button>
<Counter onClick={onClick}/>
</div>
)
}
export default App;
6 useRef => useRef 可以用来在父组件中获取子组件的句柄或调用dom属性
import React, {PureComponent, useState, useRef, useCallback} from 'react';
class Counter extends PureComponent{
init() {
console.log('---init---')
}
render() {
const {props} = this
return (
<div onClick={props.onClick}>consoleCount:{props.count}</div>
)
}
}
function App() {
const [count, setCount] = useState(0)
const CounterRef = useRef()
const onClick = useCallback(() => {
CounterRef.current.init()
}, [CounterRef])
return (
<div>
<button onClick={() => {setCount(count + 1)}}>addCount{count}</button>
<Counter count={count} ref={CounterRef} onClick={onClick}/>
</div>
)
}
export default App;