高阶组件使用场景:属性代理、反向代理


属性代理

  1. import React, {Component} from 'react';
  2. // 属性代理又分三个场景案例:
  3. // 案例一 获取被包裹组件的refs,可直接更改被包裹组件的显示内容
  4. const HOC = (WrapperComponent) => {
  5. return class extends Component {
  6. wrapper = React.createRef();
  7. componentDidMount() {
  8. console.log(this.wrapper.current.state);
  9. this.wrapper.current.setState({ text: '通过高阶组件改变的内容' });
  10. }
  11. render() {
  12. return (
  13. <WrapperComponent {...this.props} ref={this.wrapper} />
  14. );
  15. }
  16. }
  17. }
  18. // 使用高阶组件时有两种写法
  19. // 写法一如下
  20. class NormalComponent extends Component {
  21. constructor(props) {
  22. super(props);
  23. this.state = {
  24. text: 'Hello Shang Hai'
  25. }
  26. }
  27. render() {
  28. return (
  29. <div>{this.state.text}</div>
  30. );
  31. }
  32. }
  33. export default HOC(NormalComponent);
  34. // 写法二如下(暂不支持修饰器写法,需要安装插件)
  35. @HOC
  36. class NormalComponent extends Component {
  37. constructor(props) {
  38. super(props);
  39. this.state = {
  40. text: 'Hello Shang Hai'
  41. }
  42. }
  43. render() {
  44. return (
  45. <div>{this.state.text}</div>
  46. );
  47. }
  48. }
  49. export default NormalComponent;
  50. // 案例二 抽象state,把非受控组件转变为受控组件
  51. const HOC = (WrapperComponent) => {
  52. return class extends Component {
  53. constructor(props) {
  54. super(props);
  55. this.state = {
  56. value: ''
  57. }
  58. }
  59. onChange = (e) => {
  60. this.setState({
  61. value: e.target.value
  62. })
  63. }
  64. render() {
  65. return (
  66. <WrapperComponent {...this.props} value={this.state.value} onChange={this.onChange} />
  67. );
  68. }
  69. }
  70. }
  71. // 函数式组件不能用装饰器,装饰器只能修饰类
  72. // const NormalComponent = (props) => <input {...props} type="text"/>
  73. // export default HOC(NormalComponent);
  74. // 案例三 增加新的ui内容
  75. const HOC =(WrapperComponent) => {
  76. return class extends Component {
  77. static defaultProps = {
  78. label: 'gaojiezujian'
  79. }
  80. render() {
  81. console.log("this.props:", this.props);
  82. return (
  83. <div>
  84. <label>{this.props.label}</label>
  85. <WrapperComponent {...this.props}/>
  86. </div>
  87. );
  88. }
  89. }
  90. }
  91. class NormalComponent extends Component {
  92. render() {
  93. return (
  94. <input type="text" />
  95. );
  96. }
  97. }
  98. export default HOC(NormalComponent);

反向代理

  1. import React, {Component} from 'react';
  2. // 高阶组件
  3. // 由于Enchance 类继承了WrapperComponent 类,而不是WrapperComponent 类继承其他类,所以称之为反向继承。
  4. // 反向继承相对于属性代理更加灵活,可以进行一些个性化操作。
  5. const HOC = (WrapperComponent) => {
  6. return class Enchance extends WrapperComponent {
  7. constructor(props) {
  8. super(props);
  9. this.state = {
  10. text: '高阶组件的反向代理'
  11. }
  12. }
  13. render() {
  14. // return super.render();
  15. // 以下三行代码便是渲染劫持的具体实现,修改由render方法输出的React组件树。
  16. const domTree = super.render();
  17. const style = {color: 'red'};
  18. return React.cloneElement(domTree, {style});
  19. }
  20. }
  21. }
  22. // 普通组件
  23. class NormalComponent extends Component {
  24. constructor(props) {
  25. super(props);
  26. this.state = {
  27. text: '这是个普通组件'
  28. }
  29. }
  30. render() {
  31. return (
  32. <div>{this.state.text}</div>
  33. );
  34. }
  35. }
  36. export default HOC(NormalComponent);