[react] 無狀態組件 與 高階組件


高階組件

通過函數和閉包,改變已有組件的行為,
本質上就是 Decorator 模式在React的一種實現。

  • 定義
import { Component } from "React" ;

export const Enhance = (ComposedComponent) => {
	return class extends Component {
		constructor() {
			this.state = { data: null };
		}
		componentDidMount() {
			this.setState({ data: 'Hello' });
		}
		render() {
			return <ComposedComponent {...this.props} data={this.state.data} />;
		}
	}
}

Enhance 是一個方法,當傳入一個 Component(ComposedComponent) 的時候,
它將自動為該 Component 進行擴展並返回新的類定義。
Enhance 中就返回了一個擴展的 Component 類,為構造函數中添加了 state,
也在 React 生命周期函數 componentDidMount中添加了處理邏輯,
而 render 方法則使用了傳入的參數,完成了渲染。

  • 用法

import  { Component }  from "React";
import { Enhance } from "./Enhance";

class MyComponent = class extends Component {
      render() {
          if (!this.props.data) return <div>Waiting...</div>;
          return <div>{this.props.data}</div>;
      }
}

export default Enhance(MyComponent); // Enhanced component`

  • 另一個例子

function connectPromise({promiseLoader, mapResultToProps}) {
  return Comp=> {
    return class AsyncComponent extends Component {
      constructor(props) {
        super();
        this.state = {
          result: undefined
        }
      }
      componentDidMount() {
        promiseLoader()
          .then(result=> this.setState({result}))
      }
      render() {
        return (
          <Comp {...mapResultToProps(props)} {...this.props}/>
        )
      }
    }
  }
}


const UserList = connectPromise({
    promiseLoader: loadUsers,
    mapResultToProps: result=> ({list: result.userList})
})(List); //List can be a pure component

const BookList = connectPromise({
    promiseLoader: loadBooks,
    mapResultToProps: result=> ({list: result.bookList})
})(List);

無狀態組件

findDOMNode和refs都無法用於無狀態組件中,無狀態組件掛載時只是方法調用,沒有新建實例。

當無狀態組件需要使用到生命周期時,可使用高階組件包裝。

function HelloComponent(props, /* context */) {
  return <div>Hello {props.name}</div>
}
ReactDOM.render(<HelloComponent name="Sebastian" />, mountNode)
function Input({ label, name, value, ...props }, { defaultTheme }) {
  const { theme, autoFocus, ...rootProps } = props
  return (
    <label
      htmlFor={name}
      children={label || defaultLabel}
      {...rootProps}
    >
    <input
      name={name}
      type="text"
      value={value || ''}
      theme={theme || defaultTheme}
      {...props}
    />
  )}
Input.contextTypes = {defaultTheme: React.PropTypes.object};


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM