[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};
 
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号