【问题标题】:React ref.current is null in componentDidMount only in Enzyme test, NOT null in real timeReact ref.current 在 componentDidMount 中仅在酶测试中为空,而不是实时为空
【发布时间】:2019-08-13 00:56:50
【问题描述】:

我对测试 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 未定义。

谁能帮我理解发生了什么?谢谢!

【问题讨论】:

标签: reactjs unit-testing enzyme


【解决方案1】:

我猜这仅在 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);

查看您的代码,以下修复可能会起作用。你有 在从 实例。

//Component
export default class Tab extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = createRef();
  }
  componentDidMount() {
    console.log("TAB Component Did Mount, REF is : ", this.myRef);
  }

  render() {
    return (
      <div className="tab_bar">
        <ul
          ref={this.myRef}
          className="tab__list direction--row"
          role="tablist"
        >
          <li>TEST</li>
        </ul>
      </div>
    );
  }
}

//Test
describe("Tab component", () => {
  it("Ref should be available in instance", () => {
    const wrapper = mount(<Tab />);
    const ulElement = wrapper.find("ul");

    expect(ulElement.instance()).not.toBeNull();
    expect(wrapper.instance()).not.toBeNull();

    expect(ulElement.instance()).toBe(wrapper.instance().myRef.current);
  });
});

编辑:工作沙箱实例 https://codesandbox.io/s/enzyme-instance-3rktt

确保您的 Adapter 版本React 版本 相同

【讨论】:

  • 谢谢。我认为问题在于我没有正确的适配器。我无法确定,因为目前无法获得那个新适配器,但我恢复到回调 refs 并且工作正常。
  • 好像还是不行。我刚刚验证了componentDidMount 中的ref 仍然为空,版本为"react": "16.10.2""enzyme-adapter-react-16": "1.15.1"
  • @JBSnorro 立即查看答案
猜你喜欢
  • 1970-01-01
  • 2019-08-10
  • 2017-08-25
  • 1970-01-01
  • 2018-06-21
  • 1970-01-01
  • 1970-01-01
  • 2020-09-14
  • 2014-11-24
相关资源
最近更新 更多