Create fetching review for reactjs app

If it is just one simple api request, then you are better of with using Context API. Just call the API with any network library such as fetch or axios, and keep data inside the Context. And use that Context in the whole App.

As the application's complexity grows and you need more functionality you can then use more sophisticated libraries such as Redux for managing state(keeping data at client app), calls to API will still be done with fetch or axios.

This page assumes you’re using Jest as a test runner. If you use a different test runner, you may need to adjust the API, but the overall shape of the solution will likely be the same. Read more details on setting up a testing environment on the Testing Environments page.

On this page, we will primarily use function components. However, these testing strategies don’t depend on implementation details, and work just as well for class components too.


Setup/Teardown

For each test, we usually want to render our React tree to a DOM element that’s attached to

act(() => {
  // render components
});
// make assertions

5. This is important so that it can receive DOM events. When the test ends, we want to “clean up” and unmount the tree from the

act(() => {
  // render components
});
// make assertions

5.

A common way to do it is to use a pair of

act(() => {
  // render components
});
// make assertions

7 and

act(() => {
  // render components
});
// make assertions

8 blocks so that they’ll always run and isolate the effects of a test to itself:

import { unmountComponentAtNode } from "react-dom";
let container = null;
beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);
});
afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});

You may use a different pattern, but keep in mind that we want to execute the cleanup even if a test fails. Otherwise, tests can become “leaky”, and one test can change the behavior of another test. That makes them difficult to debug.


act(() => {
  // render components
});
// make assertions

4

When writing UI tests, tasks like rendering, user events, or data fetching can be considered as “units” of interaction with a user interface.

// hello.js
import React from "react";
export default function Hello(props) {
  if (props.name) {
    return 

Hello, {props.name}!

; } else { return Hey, stranger; } }

0 provides a helper called that makes sure all updates related to these “units” have been processed and applied to the DOM before you make any assertions:

act(() => {
  // render components
});
// make assertions

This helps make your tests run closer to what real users would experience when using your application. The rest of these examples use

act(() => {
  // render components
});
// make assertions

4 to make these guarantees.

You might find using

act(() => {
  // render components
});
// make assertions

4 directly a bit too verbose. To avoid some of the boilerplate, you could use a library like React Testing Library, whose helpers are wrapped with

act(() => {
  // render components
});
// make assertions

4.

Note:

The name

// hello.js import React from "react"; export default function Hello(props) { if (props.name) { return

Hello, {props.name}!

; } else { return Hey, stranger; } }

5 comes from the Arrange-Act-Assert pattern.

Rendering

Commonly, you might want to test whether a component renders correctly for given props. Consider a simple component that renders a message based on a prop:

// hello.js
import React from "react";
export default function Hello(props) {
  if (props.name) {
    return 

Hello, {props.name}!

; } else { return Hey, stranger; } }

We can write a test for this component:

// hello.test.js
import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";
import Hello from "./hello";
let container = null;
beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);
});
afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});
it("renders with or without a name", () => {
  act(() => {    render(, container);  });  expect(container.textContent).toBe("Hey, stranger");
  act(() => {
    render(, container);
  });
  expect(container.textContent).toBe("Hello, Jenny!");
  act(() => {
    render(, container);
  });
  expect(container.textContent).toBe("Hello, Margaret!");
});


Data Fetching

Instead of calling real APIs in all your tests, you can mock requests with dummy data. Mocking data fetching with “fake” data prevents flaky tests due to an unavailable backend, and makes them run faster. Note: you may still want to run a subset of tests using an framework that tells whether the whole app is working together.

// user.js
import React, { useState, useEffect } from "react";
export default function User(props) {
  const [user, setUser] = useState(null);
  async function fetchUserData(id) {
    const response = await fetch("/" + id);
    setUser(await response.json());
  }
  useEffect(() => {
    fetchUserData(props.id);
  }, [props.id]);
  if (!user) {
    return "loading...";
  }
  return (
    
{user.name} {user.age} years old
lives in {user.address}
); }

We can write tests for it:

// user.test.js
import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";
import User from "./user";
let container = null;
beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);
});
afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});
it("renders user data", async () => {
  const fakeUser = {    name: "Joni Baez",    age: "32",    address: "123, Charming Avenue"  };  jest.spyOn(global, "fetch").mockImplementation(() =>    Promise.resolve({      json: () => Promise.resolve(fakeUser)    })  );
  // Use the asynchronous version of act to apply resolved promises
  await act(async () => {
    render(, container);
  });
  expect(container.querySelector("summary").textContent).toBe(fakeUser.name);
  expect(container.querySelector("strong").textContent).toBe(fakeUser.age);
  expect(container.textContent).toContain(fakeUser.address);
  // remove the mock to ensure tests are completely isolated  global.fetch.mockRestore();});


Mocking Modules

Some modules might not work well inside a testing environment, or may not be as essential to the test itself. Mocking out these modules with dummy replacements can make it easier to write tests for your own code.

Consider a

// hello.js
import React from "react";
export default function Hello(props) {
  if (props.name) {
    return 

Hello, {props.name}!

; } else { return Hey, stranger; } }

6 component that embeds a third-party

// hello.js
import React from "react";
export default function Hello(props) {
  if (props.name) {
    return 

Hello, {props.name}!

; } else { return Hey, stranger; } }

7 component:

// map.js
import React from "react";
import { LoadScript, GoogleMap } from "react-google-maps";
export default function Map(props) {
  return (
    
      
    
  );
}
// contact.js
import React from "react";
import Map from "./map";
export default function Contact(props) {
  return (
    
Contact {props.name} via{" "} email or on their website .
); }

If we don’t want to load this component in our tests, we can mock out the dependency itself to a dummy component, and run our tests:

// contact.test.js
import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";
import Contact from "./contact";
import MockedMap from "./map";
jest.mock("./map", () => {  return function DummyMap(props) {    return (      
{props.center.lat}:{props.center.long}
); };}); let container = null; beforeEach(() => { // setup a DOM element as a render target container = document.createElement("div"); document.body.appendChild(container); }); afterEach(() => { // cleanup on exiting unmountComponentAtNode(container); container.remove(); container = null; }); it("should render contact information", () => { const center = { lat: 0, long: 0 }; act(() => { render( , container ); }); expect( container.querySelector("[data-testid='email']").getAttribute("href") ).toEqual("mailto:[email protected]"); expect( container.querySelector('[data-testid="site"]').getAttribute("href") ).toEqual("http://test.com"); expect(container.querySelector('[data-testid="map"]').textContent).toEqual( "0:0" ); });


Events

We recommend dispatching real DOM events on DOM elements, and then asserting on the result. Consider a

// hello.js
import React from "react";
export default function Hello(props) {
  if (props.name) {
    return 

Hello, {props.name}!

; } else { return Hey, stranger; } }

8 component:

// toggle.js
import React, { useState } from "react";
export default function Toggle(props) {
  const [state, setState] = useState(false);
  return (
    
  );
}
`

We could write tests for it:
// toggle.test.js import React from "react"; import { render, unmountComponentAtNode } from "react-dom"; import { act } from "react-dom/test-utils"; import Toggle from "./toggle"; let container = null; beforeEach(() => { // setup a DOM element as a render target container = document.createElement("div"); document.body.appendChild(container);}); afterEach(() => { // cleanup on exiting unmountComponentAtNode(container); container.remove(); container = null; }); it("changes value when clicked", () => { const onChange = jest.fn(); act(() => {
render(, container);
}); // get a hold of the button element, and trigger some clicks on it const button = document.querySelector("[data-testid=toggle]"); expect(button.innerHTML).toBe("Turn on"); act(() => {
button.dispatchEvent(new MouseEvent("click", { bubbles: true }));
}); expect(onChange).toHaveBeenCalledTimes(1); expect(button.innerHTML).toBe("Turn off"); act(() => {
for (let i = 0; i < 5; i++) {
  button.dispatchEvent(new MouseEvent("click", { bubbles: true }));
}  });
expect(onChange).toHaveBeenCalledTimes(6); expect(button.innerHTML).toBe("Turn on"); });

Different DOM events and their properties are described in MDN. Note that you need to pass 
// hello.js import React from "react"; export default function Hello(props) { if (props.name) {
return 

Hello, {props.name}!

;
} else {
return Hey, stranger;
} }

9 in each event you create for it to reach the React listener because React automatically delegates events to the root.
Note: React Testing Library offers a more concise helper for firing events.

### Timers Your code might use timer-based functions like
// hello.test.js import React from "react"; import { render, unmountComponentAtNode } from "react-dom"; import { act } from "react-dom/test-utils"; import Hello from "./hello"; let container = null; beforeEach(() => { // setup a DOM element as a render target container = document.createElement("div"); document.body.appendChild(container); }); afterEach(() => { // cleanup on exiting unmountComponentAtNode(container); container.remove(); container = null; }); it("renders with or without a name", () => { act(() => { render(, container); }); expect(container.textContent).toBe("Hey, stranger"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Jenny!"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Margaret!"); });

0 to schedule more work in the future. In this example, a multiple choice panel waits for a selection and advances, timing out if a selection isn’t made in 5 seconds:
act(() => { // render components }); // make assertions

0

We can write tests for this component by leveraging Jest’s timer mocks, and testing the different states it can be in.
act(() => { // render components }); // make assertions

1

You can use fake timers only in some tests. Above, we enabled them by calling 
// hello.test.js import React from "react"; import { render, unmountComponentAtNode } from "react-dom"; import { act } from "react-dom/test-utils"; import Hello from "./hello"; let container = null; beforeEach(() => { // setup a DOM element as a render target container = document.createElement("div"); document.body.appendChild(container); }); afterEach(() => { // cleanup on exiting unmountComponentAtNode(container); container.remove(); container = null; }); it("renders with or without a name", () => { act(() => { render(, container); }); expect(container.textContent).toBe("Hey, stranger"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Jenny!"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Margaret!"); });

1\. The main advantage they provide is that your test doesn’t actually have to wait five seconds to execute, and you also didn’t need to make the component code more convoluted just for testing.


### Snapshot Testing Frameworks like Jest also let you save “snapshots” of data with
// hello.test.js import React from "react"; import { render, unmountComponentAtNode } from "react-dom"; import { act } from "react-dom/test-utils"; import Hello from "./hello"; let container = null; beforeEach(() => { // setup a DOM element as a render target container = document.createElement("div"); document.body.appendChild(container); }); afterEach(() => { // cleanup on exiting unmountComponentAtNode(container); container.remove(); container = null; }); it("renders with or without a name", () => { act(() => { render(, container); }); expect(container.textContent).toBe("Hey, stranger"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Jenny!"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Margaret!"); });

2 / 
// hello.test.js import React from "react"; import { render, unmountComponentAtNode } from "react-dom"; import { act } from "react-dom/test-utils"; import Hello from "./hello"; let container = null; beforeEach(() => { // setup a DOM element as a render target container = document.createElement("div"); document.body.appendChild(container); }); afterEach(() => { // cleanup on exiting unmountComponentAtNode(container); container.remove(); container = null; }); it("renders with or without a name", () => { act(() => { render(, container); }); expect(container.textContent).toBe("Hey, stranger"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Jenny!"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Margaret!"); });

3\. With these, we can “save” the rendered component output and ensure that a change to it has to be explicitly committed as a change to the snapshot.

In this example, we render a component and format the rendered HTML with the 
// hello.test.js import React from "react"; import { render, unmountComponentAtNode } from "react-dom"; import { act } from "react-dom/test-utils"; import Hello from "./hello"; let container = null; beforeEach(() => { // setup a DOM element as a render target container = document.createElement("div"); document.body.appendChild(container); }); afterEach(() => { // cleanup on exiting unmountComponentAtNode(container); container.remove(); container = null; }); it("renders with or without a name", () => { act(() => { render(, container); }); expect(container.textContent).toBe("Hey, stranger"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Jenny!"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Margaret!"); });

4 package, before saving it as an inline snapshot:
act(() => { // render components }); // make assertions

2

It’s typically better to make more specific assertions than to use snapshots. These kinds of tests include implementation details so they break easily, and teams can get desensitized to snapshot breakages. Selectively can help reduce the size of snapshots and keep them readable for the code review.


### Multiple Renderers In rare cases, you may be running a test on a component that uses multiple renderers. For example, you may be running snapshot tests on a component with
// hello.test.js import React from "react"; import { render, unmountComponentAtNode } from "react-dom"; import { act } from "react-dom/test-utils"; import Hello from "./hello"; let container = null; beforeEach(() => { // setup a DOM element as a render target container = document.createElement("div"); document.body.appendChild(container); }); afterEach(() => { // cleanup on exiting unmountComponentAtNode(container); container.remove(); container = null; }); it("renders with or without a name", () => { act(() => { render(, container); }); expect(container.textContent).toBe("Hey, stranger"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Jenny!"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Margaret!"); });

5, that internally uses 
// hello.test.js import React from "react"; import { render, unmountComponentAtNode } from "react-dom"; import { act } from "react-dom/test-utils"; import Hello from "./hello"; let container = null; beforeEach(() => { // setup a DOM element as a render target container = document.createElement("div"); document.body.appendChild(container); }); afterEach(() => { // cleanup on exiting unmountComponentAtNode(container); container.remove(); container = null; }); it("renders with or without a name", () => { act(() => { render(, container); }); expect(container.textContent).toBe("Hey, stranger"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Jenny!"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Margaret!"); });

6 from 
// hello.test.js import React from "react"; import { render, unmountComponentAtNode } from "react-dom"; import { act } from "react-dom/test-utils"; import Hello from "./hello"; let container = null; beforeEach(() => { // setup a DOM element as a render target container = document.createElement("div"); document.body.appendChild(container); }); afterEach(() => { // cleanup on exiting unmountComponentAtNode(container); container.remove(); container = null; }); it("renders with or without a name", () => { act(() => { render(, container); }); expect(container.textContent).toBe("Hey, stranger"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Jenny!"); act(() => {
render(, container);
}); expect(container.textContent).toBe("Hello, Margaret!"); });

7 inside a child component to render some content. In this scenario, you can wrap updates with 
act(() => { // render components }); // make assertions

4s corresponding to their renderers.
act(() => { // render components }); // make assertions `

3


Something Missing?

If some common scenario is not covered, please let us know on the issue tracker for the documentation website.

How do I create a fetch request in React?

Using the Fetch API in React.

fetch('https://api.example.com/data').

then(response => response. json()).

then(data => console. log(data)).

catch(error => console. error(error));.

How do you fetch data before rendering in React?

For class components, you can also use async/await inside the componentDidMount method to fetch data, but it won't fetch the data before rendering, instead it will trigger a re-render, note that the method componentWillMount has been deprecated. the only way to fetch data before rendering is using the useEffect hook.

How do you store fetched data in React?

Create a FetchInfo() Callback Function to Fetch and Store Data. We will create a callback function that will store the user's data and then use the useEffect() hook to make the function run every time the page loads. Now we get the data from the API using the fetch() method in the data variable.

How do I review react JS code?

Checklist.

Does the project have a Readme file with instructions how to run locally and other useful info?.

Does the code run without errors?.

Does the application work as intended?.

Does it look good on mobile?.

Does the codebase use eslint? If not, why?.

Make sure no dist files, editor/IDE files, etc are checked in..