为什么显示此错误:“必须返回一个有效的React元素(或null)。您可能返回了undefined”

时间:2018-06-28 22:41:52

标签: javascript reactjs higher-order-components

我知道这个问题已经回答了,但是我只是无法解决发生了什么问题。我有一个包装器功能:

const withTracker = (WrappedComponent, partnerTrackingCode, options = {}) => {
  const trackPage = (page) => {
    ReactGA.set({
      page,
      options
    });
    ReactGA.pageview(page);
  };

  class HOC extends Component {
    componentDidMount() {
      ReactGA.initialize(partnerTrackingCode);
      const page = this.props.location.pathname;
      trackPage(page);
    }

    componentWillReceiveProps(nextProps) {
      const currentPage = this.props.location.pathname;
      const nextPage = nextProps.location.pathname;

      if (currentPage !== nextPage) {
        trackPage(nextPage);
      }
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  }

  return HOC;
};

export default withTracker;

我在这里叫它:

export default (props) => {
  const MainComponent = (
    <div>
      ...
    </div>
  );
  if (props.partnerTrackingCode) {
    return (
      withTracker(MainComponent, props.partnerTrackingCode)
    );
  }
  return (<div />);
};

定义跟踪代码并调用withTracker时,即使mainComponent是一个组件,也会向我显示此错误:A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object 我也尝试用空的div替换WrappedComponent:

return(<div />)

但仍然是相同的错误

2 个答案:

答案 0 :(得分:1)

似乎您在这里混淆元素和组件。您正在传递元素(要呈现的实际输出),而HOC是组件(通常需要一组道具并返回元素的函数)。您正在向HOC传递元素,因此当它尝试呈现它(在HOC呈现函数中)时,它将无法呈现它,并且会出现错误。

要解决此问题,首先需要将MainComponent变成一个实际的组件,而不仅仅是要返回的元素,例如:

const MainComponent = props => (
  <div>
    ...
  </div>
)

然后将其与包装器一起使用,然后将其渲染:

if (props.partnerTrackingCode) {
  const MainWithTracker = withTracker(MainComponent, props.partnerTrackingCode)
  return <MainWithTracker />;
}

这有点奇怪,因为您需要在render方法中创建包装的组件,这通常不是您要做的事情。更改您的HOC可能更有意义,以便它返回一个以partnerTrackingCode作为prop而不是HOC参数的组件。类似于:

// your HOC (omitting irrelevant bits)
const withTracker = (WrappedComponent, options = {}) => {

  ...

  class HOC extends Component {
    componentDidMount() {
      ReactGA.initialize(this.props.partnerTrackingCode);
      ...
    }

    ...

    render() {
      // pull out the tracking code so it doesn't get passed through to the
      // wrapped component
      const { partnerTrackingCode, ...passthrough } = this.props;
      return <WrappedComponent {...passthrough} />;
    }
  }

  return HOC;
};

// in your component
const MainComponent = props => (
  <div>
    ...
  </div>
);
const MainWithTracker = withTracker(MainComponent);

export default (props) => {
  if (props.partnerTrackingCode) {
    return (<MainWithTracker partnerTrackingCode={props.partnerTrackingCode} />);
  }
  return (<div />);
};

(我认为这不是最好的方法,我只是尽我所能地保持与您的代码接近。一旦您开始对其进行重组,就可以更好地了解所尝试的内容可以找到一种更好的组织方式。)

答案 1 :(得分:0)

您的退货方法中的问题,第一步您必须了解 当您要呼叫HOC时,您必须这样写

  return withTracker(MainComponent, props.partnerTrackingCode)

代替这个

  return (
  withTracker(MainComponent, props.partnerTrackingCode)
  );

删除()

然后再次检查,如果仍然有错误告诉我