0

使用 recompose 创建 HoC 时withState出错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`.

我的组件树如下所示:

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);
4

1 回答 1

0

SimpleImage组件仍然具有对无状态功能组件的引用,this并且state尽管它是无状态功能组件。删除这些引用并替换this.onLoadonLoadthis.onFailwithonFail和更改this.state.statuswithstatus可以正常工作。

更新后的SimpleImage组件如下所示:

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>);
}
于 2016-12-01T16:22:37.487 回答