仅在酶测试中,react ref.current在componentDidMount中为null,实时不为null

时间:2019-03-22 04:14:56

标签: reactjs unit-testing enzyme

我对测试React组件还很陌生,并且正在努力测试使用React.createRef创建的ref。我已经读完了这个很棒的回复  我不确定它是否解决了我的问题。 componentDidMount called BEFORE ref callback

constructor(props) {
    super(props);
    this.myRef = React.createRef();
    console.log('this.myRef in constructor', this.myRef);
}

此控制台日志返回null,这是预期的,因为该组件尚未呈现。

componentDidMount() {
    console.log('this.myRef in component did mount', this.myRef);
  }
    return (
      <div className="tab_bar">
        <ul ref={this.myRef} className="tab__list direction--row" role="tablist">
          { childrenWithProps }
        </ul>
      </div>

控制台日志返回componentDidMount中的ul html元素。这也是可以预期的,因为组件已渲染。

但是,

当我测试此组件时:

const children = <div> child </div>;

describe('Tab component', () => {
  it('should render', () => {
    const wrapper = mount(<Tab>{children}</Tab>);
    const ulElement = wrapper.find('ul');
    const instance = ulElement.instance().ref;
    console.log('instance', instance);

    expect(wrapper).toMatchSnapshot();
  });
});

我的终端中的控制台日志语句(构造函数和componentDidMount中的this.myRef)都说{current: null}instance是未定义的。

任何人都可以帮助我了解发生了什么吗?谢谢!

1 个答案:

答案 0 :(得分:0)

我猜这仅在React 16.3或更高版本中受支持。并应安装16.3适配器! 在this中查看下面复制的测试实现示例。

  class Foo extends React.Component {
    constructor(props) {
      super(props);
      this.setRef = createRef();
    }
     render() {
      return (
        <div>
          <div ref={this.setRef} className="foo" />
        </div>
      );
    }
  }

  const wrapper = mount(<Foo />);
  const element = wrapper.find('.foo').instance();
  expect(wrapper.instance().setRef).to.have.property('current', element);
  

查看您的代码,以下修复可能应该起作用。你有   从网站访问引用时使用引用的名称“ myRef”   实例。

describe('Tab component', () => {
  it('should render', () => {
    const wrapper = mount(<Tab>{children}</Tab>);
    const ulElement = wrapper.find('ul');
    const instance = ulElement.instance().myRef; //changed ref to myRef
    console.log('instance', instance);

    expect(wrapper).toMatchSnapshot();
  });
});