React-demo
react-demo: https://github.com/Zjingwen/react-demo欢迎git clone复制代码
React的方法
生命周期详解
constructor 实例化
class A extends React.Component{ constructor(){ super(); }}复制代码
- 实例化对象
- 继承React.Component
- 初始化state
static getDerivedStateFromProps
class A extends React.Component{ static getDerivedStateFromProps(props,state){ return Object }}复制代码
- update更新时,render之前,dom渲染前
- 必须有初始化state
- 静态方法,没有this
- 可以return出对象,设置state
class Count extends Component{ constructor(props){ super(props); this.state = { count: 0, } }; static getDerivedStateFromProps(props){ return {count: props.count*2}; }; render(){ return ()};复制代码) }};class Time extends Component{ constructor(props){ super(props); this.state={ time: this.props.time, } }; static getDerivedStateFromProps(props,state){ console.log(state); return null; }; handleClick(){ this.setState({ time: new Date().toString() }); } render(){ const {time} = this.state; return( Count-Child-state: {this.state.count}
Count-Child-props: {this.props.count}
this.handleClick()}/> ) };};function GetDerivedStateFromPropsComponent (){ const [count,setCount] = useState(0); const [time] = useState(new Date().toString()); return ({time}
shouldComponentUpdate
class A extends React.Component{ shouldComponentUpdate(nextProps, nextState){ return Boolean }}复制代码
- update更新时,render之前,dom渲染前
- return 一个布尔值来判断是否渲染
- 默认return true
class Time extends Component{ shouldComponentUpdate(nextPorps){ if(this.props.time !== nextPorps.time){ // 保证每次time不同时更新 console.group('shouldComponent-props'); console.log(nextPorps); console.log(this.props); console.groupEnd(); return true; } return false; }; render(){ return()};复制代码{this.props.time} ) }};function ShuldComponentUpdateComponent() { const [time,setTime] = useState(new Date().toString()); return(
render
class A extends React.Component{ render(){ return JSX }}复制代码
- 将jsx渲染为真实DOM
getShapshotBeforeUpdate
class A extends React.Component{ getShapshotBeforeUpdate(prevProps,prevState){ return ‘getShapshotBeforeUpdate’ } componentDidUpdate(prevProps,prevState,snapshot){ // TODO snapshot == ‘getShapshotBeforeUpdate’ }}复制代码
- update更新时,render之前,dom渲染前
- 无默认返回值,可返回null
- return 一个值,用来作为componentDidUpdate的第三个参数
class Child extends Component { constructor(props) { super(props); this.state = { ...props, }; } getSnapshotBeforeUpdate(prevProps, prevState) { console.group('getSnapshotBeforeUpdate'); console.log(prevProps); console.log(prevState); console.groupEnd(); if (prevProps.time !== prevState.time) { this.setState({ time: prevProps.time, }); } return 'getSnapshotBeforeUpdate'; } componentDidUpdate(prevProps, prevState, snapshot) { console.group('componentDidUpdate'); console.log(prevProps); console.log(prevState); console.log(snapshot); console.groupEnd(); } render() { return ();}复制代码{this.state.time}
); }}function GetShapshotBeforeUpdateComponent() { const [time, setTime] = useState(new Date().toString()); return (
componentDidMount
class A extends React.Component{ componentDidMount(){}}复制代码
- render之后,dom渲染后
- 唯一的会在服务端渲染调起的生命周期钩子函数。
class Time extends Component { componentDidMount() { console.log('ComponentDidMount'); } render() { return ();}复制代码{new Date().toString()}
); }}function ComponentDidMountComponent() { const [show, setShow] = useState(false); return (
componentDidUpdate
class A extends React.Component{ componentDidUpdate(prevProps,prevState,snapshot){}}复制代码
- update更新时,render之后,dom渲染后
- snapshot为getShapshotBeforeUpdate的return
参照getShapshotBeforeUpdate的code demo复制代码
componentWillUnmount
class A extends React.Component{ componentWillUnmount(){}}复制代码
- dom卸载
class Time extends Component { componentWillUnmount() { console.log('componentWillUnmount'); } render() { return ();}复制代码{new Date().toString()}
); };}function ComponentWillUnmountComponent() { const [show, setShow] = useState(true); return (
componentDidCatch
class A extends React.Component{ componentDidCatch(error,errorInfo){}}复制代码
- 只有在render中报错才会被捕获
- 为什么不用try/catch:try/catch更加适合命令式代码,而componentDidCatch会捕获组件树中的报错
class ErrorBoundary extends Component { constructor(props) { super(props); this.state={ error: false, errorInfo: null, }; } componentDidCatch(error, errorInfo) { console.log(errorInfo.componentStack); this.setState({ error: error.toString(), errorInfo: errorInfo.componentStack, }); } render() { if (this.state.error) { return ();};复制代码); } return this.props.children; }};ErrorBoundary.propTypes = { children: PropTypes.node.isRequired,};class Input extends Component { constructor() { super(); this.state= { throw: false, }; } handleClick() { this.setState((s)=>({ throw: !s.throws, })); } render() { if (this.state.throw) throw new Error('I throw'); return this.handleClick()} />; }};function ComponentDidCatchComponent() { return (error: {this.state.error}
errorInfo:{this.state.errorInfo}
触发流程
初始化
constructor()static getDerivedStateFromProps(props,state)render()componentDidMount()复制代码
class Flow extends React.Component{ constructor(){ super(); this.state = {}; console.group('初始化阶段'); console.log('constructor'); }; static getDerivedStateFromProps(){ console.log('getDerivedStateFromProps'); return null; }; componentDidMount(){ console.log('componentDidMount'); console.groupEnd(); } render(){ console.log('render'); return ()};复制代码constructor
| static getDerivedStateFromProps() | render | componentDidMount ) };}function MountingComponent (){ const [show,setShow] = useState(false); return (
属性更新
New Props
static getDerivedStateFromProps(props,state)shouldComponentUpdate(nextProps, nextState)render()getSnapshotBeforeUpdate(prevProps,prevState)componentDidUpdate()复制代码
class Flow extends React.Component{ state = {}; static getDerivedStateFromProps(){ console.group('触发传递新的props'); console.log('getDevivedStateFromProps'); return null; }; shouldComponentUpdate(){ console.log('shouldComponentUpdate'); return true; }; getSnapshotBeforeUpdate(){ console.log('getSnapshotBeforeUpdate'); return null; }; componentDidUpdate(){ console.log('componentDidUpdate'); console.groupEnd(); }; render(){ console.log('render'); return()};export default NewpropsComponent;复制代码) }};function NewpropsComponent(){ const [time,setTime] = useState(new Date().toString()); return ( {this.props.title}
static getDevivedStateFromPorps
| shouldComponentUpdate | getSnapshotBeforeUpdate | componentDidUpdate
setState()
static getDerivedStateFromProps()shouldComponentUpdate()render()getSnapshotBeforeUpdate()componentDidUpdate()复制代码
class SetStateComponent extends React.Component{ state = { time: new Date().toString(), }; static getDerivedStateFromProps(){ console.group('设置属性'); console.log('getDerivedStateFromProps'); return null; }; shouldComponentUpdate(){ console.log('shouldComponentUpdate') return true; }; getSnapshotBeforeUpdate(){ console.log('getSnapshotBeforeUpdate'); return null; }; componentDidUpdate(){ console.log('componentDidUpdate'); console.groupEnd(); }; handleClick(){ this.setState({ time: new Date().toString() }); } render(){ console.log('render'); return () }}复制代码
forceUpdate()
getDerivedStateFromProps()render()getShapshotBeforeUpdate()componentDidUpdate()复制代码
class ForceUpdateComponent extends React.Component{ state = {}; static getDerivedStateFromProps(){ console.group('forecUpdate更新'); console.log('getDerivedStateFromProps'); return true; }; getSnapshotBeforeUpdate(){ console.log('getShapshotBeforeUpdate'); return null; }; componentDidUpdate(){ console.log('componentDidUpdate'); console.groupEnd(); } render(){ console.log('render') return() }}复制代码
触发生命周期的api
setState 设置状态
setState((State)=>({object}),function callback])复制代码
// 完全写法this.setState(State=>({ ...State}),()=>{ ...})// 简单写法this.setState({ ...})复制代码
- 触发一轮生命周期
getDerivedStateFromProps->shouldComponentUpdate->render->getSnapshotBeforeUpdate->componentDidUpdate
- prevState为当前组件的state值
- callback,为状态设置之后,state经过所有生命周期后调用
forceUpage 强制更新
forceUpage(function callback)复制代码
this.forceUpage(()=>{ ...})复制代码
- 触发一轮生命周期
getDerivedStateFromProps->render->componentDidUpdate
- callback,为生命周期之后调用
React.Component
- react的抽象基础类
class A extends React.Component{}复制代码
React.PureComponent
- 内置一个浅比较,比较props和state,决定是否render,用于提高性能
- 只是进行浅对比,无法对比复合数据
- 用于避免无状态组件的重复渲染
class A extends React.PureComponent{}复制代码
React.memo(()=>{},()=>{});
- 组件仅在它的 props 发生改变的时候进行重新渲染
- 和React.PureComponent类似功能一直,但这是一个纯函数用法
- 只是进行浅对比,无法对比复合数据
const A = React.memo((props)=>{ return JSX},(prevProps,nextProps)=>{ return null | false})复制代码
const MemoComponent = React.memo((props)=>{ return ();};复制代码{props.time});}, (prevProps, nextProps)=>{ if (prevProps.time !== nextProps.time) { return null; } return false;});function Memo() { const [time, setTime] = useState(new Date().toString()); return (
React.createRef()
- 创建节点引用
- 通过ref属性附加到React元素
- 可以通过curent访问到节点
- ref更新发生在componentDidMount、componentDidUpdate时
- 无法在函数组件上使用,因为没有实例
class CreateRefComponent extends Component { constructor() { super(); this.state = { el: null, }; this.ref = React.createRef(); } componentDidMount() { this.setState({ el: this.ref.current.innerHTML, }); } render() { return (); }}复制代码
React.isValidElement(object)
- 验证对象是否为React元素。返回true或false。
- 必须传递一个对象
let D = React.createElement('div');React.isValidElement(D);复制代码
function ChildFunction() { return ();};复制代码Child-function);};class ChildComponent extends Component { render() { return (Child-Component); }};function IsValidElementComponent() { const D = React.createElement('div'); return (
React.Children
- 遍历children,返回数组
array React.Children.map(children,function callback) 复制代码
class Map extends Component { render() { const arr = React.Children.map(this.props.children, (v)=> v); return (); }};Map.propTypes = { children: PropTypes.node.isRequired,};function Index() { return ( );};复制代码
- 遍历children,无返回
void React.Children.forEach(children,function callback) 复制代码
class ForEact extends Component { render() { const arr = []; React.Children.forEach(this.props.children, (v) => arr.push(v)); return (); }};ForEact.propTypes = { children: PropTypes.node.isRequired,};function Index() { return (
A
B
C
D
E
F
- 返回children的长度
number React.Children.count(children) 复制代码
class Count extends Component { render() { const count = React.Children.count(this.props.children, (v)=> v); return (); }};Count.propTypes = { children: PropTypes.node.isRequired,};function Index() { return (
A
B
C
D
E
F
- 判断children是否为1,不为1报错
void React.Children.only(children) 复制代码
class Only extends Component { render() { const {title} = this.props; let e = null; let o = null; try { o = React.Children.only(this.props.children); } catch (error) { e = error; }; return (); }};Only.propTypes = { children: PropTypes.node.isRequired, title: PropTypes.string.isRequired,};function Index() { return (
A
B
C
D
E
F
A
- 把children,从对象转换为数组
array React.Children.toArray(children,function callback)复制代码
class ToArray extends Component { render() { const arr = React.Children.toArray(this.props.children); return (); }};ToArray.propTypes = { children: PropTypes.node.isRequired,};function Index() { return (
A
B
C
D
E
F
React.Fragment
- 允许创建一对React.Fragment的元素,这样就不用额外创建用于包裹的元素
// 完全写法render(){ return(hello React )}// 缩略写法render(){ return( <> hello React )}复制代码
React.createElement
- 创建react对象
React.createElement( type, [props], [...children]);复制代码
class Hello extends React.Component { render() { return React.createElement('div', null, `Hello ${this.props.toWhat}`); }}ReactDOM.render( React.createElement(Hello, {toWhat: 'World'}, null), document.getElementById('root'));复制代码
React.createFactory
- 返回一个React元素的函数。
React.createFactory({ type, [props], [...children]})复制代码
function createFactory() { const li = React.createFactory('li'); const Child1 = li(null, 'child-1'); const Child2 = li(null, 'child-2'); const Root = React.createElement('ul', '', Child1, Child2); return ();}复制代码
React.cloneElement
- 克隆并返回一个新的React元素
React.cloneElement({ type, [props], [...children]})复制代码
class C extends React.Component { render(){ var D = React.createElement('div'); return React.cloneElement( D, null, 'hello React' ); }}复制代码
React.forwordRef(props,ref)
TODO @jingwen 需要独立文章分析
- 引用转发ref给组件
React.forwordRef(props,ref)复制代码
// 简单用法function Input(props) { const {forwardRef} = props; return ( );};Input.propTypes = { forwardRef: propTypes.object,};Input.defaultProps={ forwardRef: {},};class ForwardRefComponent extends Component { constructor() { super(); this.state = { refs: React.createRef(), }; } handleFocus() { const {refs: {current}} = this.state; current.focus(); } render() { const {refs} = this.state; const FancyInput = React.forwardRef((props, ref)=>{ return ; }); return (); }}复制代码
// 转发ref给后代function wrapped(Component) { class Wrapped extends React.Component { render() { const {forwardedRef, ...props} = this.props; return); }};复制代码; } } return React.forwardRef((props, ref) => { return ; });}class Input extends React.Component { constructor(props) { super(props); this.ref = React.createRef(); }; handleFocus() { const {current} = this.ref; current.focus(); } render() { const props = this.props; return ( ); }}class Hoc extends React.Component { constructor() { super(); this.state = { refs: React.createRef(), }; }; handleFocus() { const {refs: {current}} = this.state; current.handleFocus(); } render() { const {refs} = this.state; const InputHoc = wrapped(Input); return (
React.lazy or React.Suspense
- React.lazy,动态导入组件
- React.Suspense,等待导入时的显示
const TimeFun = lazy(()=> import('./TimeFun'));const TimeClass = lazy(()=> import('./TimeClass'));class Index extends Component { render() { const Time = new Date().toString(); return (); }}复制代码
class TimeClass extends React.Component { render() { const Time = new Date().toString(); returnlazy-time-class: {Time}; };};export default TimeClass;复制代码
function TimeFun() { const Time = new Date().toString(); return (lazy-time-fun: {Time});};export default TimeFun;复制代码
React.StrictMode
- 给组件的任何部分开启严格模式
- 识别具有不安全生命周期的组件
- 关于遗留字符串ref API使用的警告
- 关于已弃用的findDOMNode用法的警告
- 检测意外的副作用
- 检测遗留上下文API
class Index extends Component { render() { return (); }};复制代码
Context
- 组件设置全局参数
- createContext,设置context的默认值
const A = React.createContext('aaaa');复制代码
- Context.Provider,允许组件订阅该context的参数
- Class.contextType,设置当前组件订阅的context。当找不到Provider的时候使用。context值可以在componentDidMount、componentUpdate、componentWillUnmount、render中获取
// 两种设置形式const context = React.createContext('aaa');class A extend React.Component{ static contextType = context;}class B extend React.Component{}B.contextType = context;复制代码
- Context.Consumer,
// 简单例子const ThemeContext = React.createContext('light');class ThemedButton extends React.Component { static contextType = ThemeContext; render() { return ; }}function Toolbar(props) { return (); }}复制代码);}class Index extends Component { render() { return (
- Consumer,设置多个上下文
const themes = { light: { background: '#eeeeee', }, dark: { background: '#222222', },};const ThemeContext = createContext( themes.light,);class ThemeButton extends Component { static contextType = ThemeContext; render() { const props = this.props; const theme = this.context; return ( ); }};class Index extends Component { constructor(props) { super(props); this.state = { theme: themes.light, }; } handleTheme() { this.setState((state)=>({ theme: JSON.stringify(state.theme) === JSON.stringify(themes.dark) ? themes.light : themes.dark, })); }; render() { return (); }}复制代码
ReactDOM.createPortal
ReactDOM.createPortal( React.Component | JSX, // react组件 element,// 节点元素);复制代码
defaultProps
- 设置props的默认值
class A extends React.Component{ constructor(props){ super(props); console.log(props) }; // 集成写法 static defaultProps = { test: 'test', };}// 外置写法A.defaultPorps = { test: 'test',}复制代码
PropTypes
TODO复制代码
Render Props
- 解决组件交叉使用问题
function Cat(props) { const STYLE = { width: 20, height: 20, background: '#FF00FF', position: 'absolute', left: props.mouse.x, top: props.mouse.y, }; return ( );}Cat.propTypes = { mouse: propTypes.object.isRequired,};class Mouse extends Component { constructor(props) { super(props); this.state={ x: 0, y: 0, }; } handleMove(event) { this.setState({ x: event.clientX, y: event.clientY, }); }; render() { const STYLE = { width: 500, height: 500, background: '#eee', display: 'inline-block', }; return (); }};复制代码this.handleMove(e)}> {this.props.render(this.state)}); }}Mouse.propTypes = { render: propTypes.func.isRequired,};class Index extends Component { render() { return (
React的事件池
TODO复制代码
Hooks
useState 状态钩
- 用来设置和更新状态
const [状态变量,更新函数] = useState(默认值)复制代码
function A(){ const [count, setCount] = useState(0); return()};复制代码 Count: {count}
useEffect(function,[]) 效果钩
useEffect(()=>{ // componentDidMount // componentDidUpdate return ()=>{ // componentWillUnmount }},[]);复制代码
- useEffect是componentDidMount、componentDidUpdate、componentWillUnmount的结合。
- 默认情况下,useEffect,会在每次componentDidMount、componentDidUpdate时执行。
- 可以拿到DOM结构
function A(){ const [count,setCount] = useState(0) useEffect(()=>{ document.getElementById('useEffect-A-count').innerText = `count: ${count}`; }); function handleClick(){ setCount(count+1); }; return ()};复制代码
- 如何在组件compoenntWillUnmount时触发useEffect
function B(){ const [show,setShow] = useState(true); function Child(){ useEffect(()=>{ console.log('componentDidMount'); return ()=>{ console.log('componentWillUnmount'); } }) return)};复制代码B-Child
}; return (
- 利用第二个参数,让useEffect不会过度渲染
- 为空数组,表示不依赖props或者state,将不会更新
- 数组内表示当新的赋值,如果新值和旧值不想等,就更新
function D(){ const [count,setCount] = useState(0); const [double,setDouble] = useState(count*2); const [three,setThree] = useState(count*3); useEffect(()=>{ setDouble(count*2); },[count*2]) useEffect(()=>{ setThree(count); },[])// 为空数组,表示不依赖props或者state,将不会更新 return ()};复制代码
useLayoutEffect(function,[])
- DOM渲染前反应的钩子
- 基本配置和useEffect一致
function E(){ const [name,setName] = useState(null); useLayoutEffect(()=>{ setTimeout(()=>{ setName('useLayoutEffect'); },3000); },[]); useEffect(()=>{ setTimeout(()=>{ setName('useEffect'); },3000); },[]); return()}复制代码
useContext(createContext)
- 参数在所有子组件中都能获取
const CountContext = createContext();function F(){ function ChildA(){ const countChild = useContext(CountContext); return ()}复制代码Child A count: {countChild}
) }; function ChildB(){ const countChild = useContext(CountContext); return (Child B count: {countChild}
) }; const [count,setCount] = useState(0); return (
useReducer(reducer,initialState)
- 类似redux的功能
const [state,dispatch] = useReducer(reducer,initialState,{action});// const [属性,动作] = useReducer(动作函数,初始值属性,初始动作);// 如何触发:dispatch(type);复制代码
function reducer(state,action){ switch(action){ case 'reset': return 0; break; case 'increment': return state+1; break; case 'decrement': return state-1; break; default: return state; };};function useReduceComponent(){ const [state,dispatch] = useReducer(reducer,0,'reset'); return ();};复制代码
useCallback(()=>{},[])
- 返回一个记忆的memoized,默认情况下会记录上一次传递的值
- 可以替代shouldComponentUpdate使用
function MemoizedConst ({num}){ const memoizedCallback = useCallback(()=>{ return num; },[]); return ()};function UseCallbackComponent (){ let [num,setNum] = useState([1,2,3]); useEffect(()=>{ setTimeout(function(){ setNum([3,4,5]) },3000); },[]); return ( );};// [1,2,3]// dely 3000ms// [3,4,5]复制代码
- 保存事件,让组件不会重复创建新方法,当你重复点击时,InputComponentState的handleClick的事件总是由组件新创建的。而InputComponentCallback的handleClick会被记忆下来,不会新创建。有利于提高性能。
let InputComponentStateFunc = null;function InputComponentState(){ const [state,setState] = useState(0); function handleClick(){ setState(state=> state+1); }; console.group('InputComponentStateFunc'); console.log(InputComponentStateFunc === handleClick); console.groupEnd(); InputComponentStateFunc = handleClick; return ()};let InputComponentCallbackFunc = null;function InputComponentCallback(){ const [state,setState] = useState(0); const handleClick = useCallback((event) => { setState(state=> state+1); event.persist(); },[]); console.group('InputComponentCallbackFunc'); console.log(InputComponentCallbackFunc === handleClick); console.groupEnd(); InputComponentCallbackFunc = handleClick; return ( )};function UseCallbackComponent (){ return ( );};复制代码
useMemo(function,[])
- 和useCallback基本一致,我还没发现有什么区别Q。Q
function MemoizedLet({num}){ const memo = useMemo(()=> num,[]); return ()};function MemoizedConst({num}){ const memo = useMemo(()=> num,[num]); return ( )};function useMemoComponent(){ const [num,setNum] = useState([1,2,3]); useEffect(()=>{ setTimeout(()=>{ setNum([3,4,5]); },3000); },[]); return ( )};复制代码
useRef()
- 返回一个ref对象,这个对象将维持在组件的整个生命周期
function useRefComponent(){ const inputEl = useRef(null); function handleClick(){ inputEl.current.focus(); } return()};复制代码
useImperativeMethods(ref,()=>({}))
- 向父组件公开ref实例
- 只能应用于forwardRef(props,ref)
function FancyInput(props,ref){ const inputRef = useRef(null); useImperativeMethods(ref,()=>({ focus: ()=>{ inputRef.current.focus(); } })); return };const Input = forwardRef(FancyInput);function UseImperativeMethodsComponent(){ const fancyInputRef = useRef(null); function handleClick(){ fancyInputRef.current.focus(); }; return ()};复制代码
useMutationEffect(function,[])
- 和useEffect、useLayoutEffect类似
- useMutationEffect会在更新阶段触发
function Effect(){ const [state,setState] = useState('请看log') useEffect(()=>{ setTimeout(()=>{ console.log('useEffect'); }); },[]); useLayoutEffect(()=>{ setTimeout(()=>{ console.log('useLayoutEffect'); }); },[]); useMutationEffect(()=>{ setTimeout(()=>{ console.log('useMutationEffect'); }); },[]); return ()};复制代码{state} )}function useMutationEffectComponent(){ const [show,setShow] = useState(false); return (
HOC 高级组件
解释
- 一个参数为React组件的函数,并且返回一个新函数,一个类工厂。
优点
- 高内聚,低耦合
- 代码复用,高度模块化
基本用途
- 增删改props
- 渲染劫持
公式
React.Component function WrappedComponent(React.Component:Component)复制代码
简单例子
function WrappedComponent(Wrapped){ return class extends React.Component{ render(){ const props = { context: 'React', } return; } }};class Child extends React.Component{ render(){ return hello {this.props.context}};};class App extends React.Component{ render(){ const HOCchild = WrappedComponent(Child); return() }};复制代码App
注意
- 不要改变原始组件,使用组合的形式
// 错误示范// WrappedComponent 中会覆盖组件的componentDidMount方法// 而且使用者必须要知道被覆盖方法的具体用途,才能避免方法冲突覆盖function WrappedComponent(Wrapped) { Wrapped.prototype.componentDidMount = ()=>{ console.log('WrappedComponent'); }; return Wrapped;};class Child extends React.Component{ componentDidMount(){ console.log('Child'); } render(){ returnhello React};};class App extends React.Component{ render(){ const HOCchild = WrappedComponent(Child); return() }};复制代码
// 正确示范function wrappedComponent(Wrapped){ return class React.Component{ componentDibMount(){ console.log('componentDibMount') } };};复制代码
- 不要直接修改HOC的props,最好独立变量
// 错误示范// props中可能包含太多多余的属性,无法确保高阶组件的灵活度和可重用性function WrappedComponent(Wrapped){ return class React.Component{ return}}复制代码
// 正确function WrappedComponent(Wrapped){ return class React.Component{ const {detail} = this.props; return}}复制代码
- 包装显示名称,便于调试
function WrappedComponent(Wrapped){ class WithSubscription extends React.Component{ componentDidMount(){ console.log('WrappedComponent'); } render(){ return} }; function getDiplayName(W){ return W.displayName || W.name || 'Component'; } WithSubscription.displayName = `WithSubscription(${getDiplayName(Wrapped)})` return WithSubscription;};复制代码
- 不要在render函数中使用高阶组件
TODO复制代码
- 必须将静态方法做拷贝
TODO复制代码
- Refs属性不能传递
TODO复制代码
无ES6创建React Component
- create-react-class
TODO复制代码
动态引入 dynamic import
- React Loadable
TODO复制代码
受控制组件 or 非受控制组件
TODO复制代码