简体   繁体   中英

Error creating HoC with React and recompose

Error when using recompose to create a HoC withState and lifecycle :

warning.js?8a56:36 Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method of `AppContainer`.

My component tree looks like this:

export function SimpleImage(props) {
  const {
    src,
    width = 200,
    height = 200,
    rounded,
    circle,
    status,
    onLoad,
    onFail,
  } = props;

  const mainWrapperStyle = style({
    backgroundColor: 'white',
    backgroundSize: 'contain',
    backgroundRepeat: 'none',
    boxSizing: 'border-box',
    position: 'relative',
    width,
    height,
  });

  const roundedStyle = style({
    borderRadius: '10%',
    overflow: 'hidden',
  });

  const circularStyle = style({
    borderRadius: '50%',
    overflow: 'hidden',
  });

  const defaultImageStyle = style({
    opacity: 0,
    transisition: 'opacity 150ms ease',
  });

  const loadedImageStyle = style({
    opacity: 1,
  });

  let imageStyle = defaultImageStyle;

  let wrapperStyle = mainWrapperStyle;
  if (rounded) {
    wrapperStyle = merge(mainWrapperStyle, roundedStyle);
  } else if (circle) {
    wrapperStyle = merge(mainWrapperStyle, circularStyle);
  }

  if (status === LOADED) {
    imageStyle = merge(defaultImageStyle, loadedImageStyle);
  }

  const image = (<img
      {...imageStyle}
      src={src}
      width={width}
      height={height}
      role="presentation"
      onLoad={this.onLoad}
      onError={this.onFail}
      />);

  let statusIndicator = null;
  if (this.state.status === LOADING) {
    statusIndicator = (<LoadingIndicator />);
  } else if (this.state.status === FAILED) {
    statusIndicator = (<ErrorIndicator />);
  }

  return (<div {...wrapperStyle}>
    {statusIndicator}
    {image}
  </div>);
}

const Image = compose(
  withState(
    'status',
    'setStatus',
    ({ src })=> src? LOADING: PENDING
  ),
  withProps(
    ({ setStatus }) => ({
    onLoad() {
      setStatus(LOADED);
    },
    onFail() {
      setStatus(FAILED);
    },
    reset() {
      setStatus(PENDING)
    },
    resetToLoading() {
      setStatus(LOADING)
    },
  })),
  lifecycle({
    componentWillReceiveProps(nextProps) {
      if(nextProps.src == null){
        this.props.reset();
      } else if(nextProps.src !== this.props.src) {
        this.props.resetToLoading();
      }
    }
  })
)(SimpleImage);

The SimpleImage component still has references to this and state despite being a stateless functional component. Removing these references and replacing this.onLoad with onLoad , this.onFail with onFail and changing this.state.status with status works correctly.

The updated SimpleImage component looks like this:

export function SimpleImage(props) {
  const {
    src,
    width = 200,
    height = 200,
    rounded,
    circle,
    status,
    onLoad,
    onFail,
  } = props;

  const mainWrapperStyle = style({
    backgroundColor: 'white',
    backgroundSize: 'contain',
    backgroundRepeat: 'none',
    boxSizing: 'border-box',
    position: 'relative',
    width,
    height,
  });

  const roundedStyle = style({
    borderRadius: '10%',
    overflow: 'hidden',
  });

  const circularStyle = style({
    borderRadius: '50%',
    overflow: 'hidden',
  });

  const defaultImageStyle = style({
    opacity: 0,
    transisition: 'opacity 150ms ease',
  });

  const loadedImageStyle = style({
    opacity: 1,
  });

  let imageStyle = defaultImageStyle;

  let wrapperStyle = mainWrapperStyle;
  if (rounded) {
    wrapperStyle = merge(mainWrapperStyle, roundedStyle);
  } else if (circle) {
    wrapperStyle = merge(mainWrapperStyle, circularStyle);
  }

  if (status === LOADED) {
    imageStyle = merge(defaultImageStyle, loadedImageStyle);
  }

  debugger
  const image = (<img
      {...imageStyle}
      src={src}
      width={width}
      height={height}
      role="presentation"
      onLoad={onLoad}
      onError={onFail}
      />);

  let statusIndicator = null;
  if (status === LOADING) {
    statusIndicator = (<LoadingIndicator />);
  } else if (status === FAILED) {
    statusIndicator = (<ErrorIndicator />);
  }

  return (<div {...wrapperStyle}>
    {statusIndicator}
    {image}
  </div>);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM