this is a question about using React refs inside of specs. specifically, I am seeing different behavior in my browser from what I see when run in the test.
// app_container.test.js
import React from 'react'
import ReactDOM from 'react-dom'
import AppContainer from "./app_container"
import { render, fireEvent, waitForElement, cleanup, wait } from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
import axiosMock from 'axios'
import { useAsync } from "react-use"
afterEach(cleanup);
test("renders", () => {
const { getByTestId } = render(<AppContainer />);
expect(getByTestId("app-container")).toHaveClass("app-container");
});
test("when mounted, it loads the rings", async () => {
jest.setTimeout(15000);
const { getByTestId } = render(<AppContainer />);
const container = getByTestId('app-container')
await wait(() => expect(getByText("Abc")).toBeInTheDocument());
})
// app_container.js code
import React from 'react'
import Ring from "./ring";
import LogoContainer from './logo_container'
const rings_data = [
{ key: 2,
name: "Abc",
blurb: "Lorem ipsum."
}
]
class AppContainer extends React.Component {
state = {
ringsLoaded: false,
}
constructor(props) {
super()
this.abc_logo_inner_ref = React.createRef()
this.rings = []
}
componentDidMount() {
setTimeout(() => {
console.log("the timeout has invoked the function ")
this.rings = rings_data
console.log("this.abc_logo_inner_ref.current= ", this.abc_logo_inner_ref)
// expecting the ref to be populated with {current: (html object)} but instead it is
// {current: null}
},1000)
}
render () {
const effect = this.effect
return (
<div data-testid="app-container" style={{height: "100vh"}}
className="app-container">
<LogoContainer ref={this.abc_logo_inner_ref}
/>
{ringsLoaded ?
<div>
{this.rings.map((ele, i) =>
<Ring
ref={this.marbles_refs_array[i]}
/>)
}
</div>
: ''}
</div>
)
}
}
export default AppContainer
What is happening is that this code works for me fine in the browser. When the function is invoked in setTimeout, this.abc_logo_inner_ref is correctly attached to the DOM element created by LogoContainer
I can inspect it (while in my browser using debugger
) and it looks like so:
However, when run from my Jest spec (above), the ref is not populated, even though I am rendering the component in the test itself (see above), when I console.log the output in my test I get for these Ref objects
{current: null}
My expected result is a correctly populated Ref object where current
element points to the DOM element that was created by React when it rendered this component.