Introduction to React Native Debugger
Everybody knows that debugging is one of the most important parts of app development. Most of the developers find it difficult and time-consuming to debug an application and for it, this comes up with React Native Debugger tool to ease out the process. It has Chrome Developer Tools added with Redux debuggers. It is a desktop app that is available for Mac OS, Linux, and Windows. Even it works without a setup, unlike the other Developer tools. In this article, we will go through some examples to understand how it works and how to perform it in real-life problems.
Syntax
Below is the syntax:
Debugger.logAction({ label: 'My event',
type: 'NETWORK_REQUEST',
logType: 'SUCCESS',
data: myCustomData <-- Supported types: String, Array, Object
});
How does React Native Debugger work?
Application with Debugger:
Components inside src folder:
- components folder
- containers folder
- CSS
- js
- js
- CSS
Components inside components folder:
- Cockpit folder
- ErrorBoundary folder
People folder Components inside the Cockpit folder:
- CSS
- js
Components inside ErrorBoundary folder:
- ErrorBoundary.js
Components inside People folder:
- Person folder
- js Components inside Person folder:
- CSS
- js
Components inside containers folder
- CSS
- js
- test.js
Code:
i. index.css
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
ii. index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./containers/App";
import registerServiceWorker from "./registerServiceWorker";
ReactDOM.render(<App />, document.getElementById("root"));
registerServiceWorker();
iii. registerServiceWorker.js
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
window.location.hostname === '[::1]' ||
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export default function register() {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
const publicUrl = new URL(process.env.PUBLIC_URL, window.location); if (publicUrl.origin !== window.location.origin) {
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (!isLocalhost) { registerValidSW(swUrl);
} else { checkValidServiceWorker(swUrl);
}
});
}
}
function registerValidSW(swUrl) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
console.log('New content is available; please refresh.');
} else {
console.log('Content is cached for offline use.');
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl) {
fetch(swUrl)
.then(response => { if (
response.status === 404 ||
response.headers.get('content-type').indexOf('javascript') === -1
) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
registerValidSW(swUrl);
}
})
.catch(() => { console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}
iv. styles.css
.App {
font-family: sans-serif;
text-align: center;
}
v. Cockpit.css
.bold {
font-weight: bold;
}
.red {
color:#f279b2;
}
.Cockpit button {
border: 1px solid #74ddf7;
padding: 16px;
background-color: #d4f774;
font: inherit;
color: #464a3c;
cursor: pointer;
}
.Cockpit button:hover {
background-color: #f7869e;
color: #211f20;
}
.Cockpit button.Red {
background-color: #e386f0;
}
vi. Cockpit.js
import React from "react";
import classes from "./Cockpit.css";
const cockpit = props => {
const { people = [], clicked, showPeople } = props;
const assignedClasses = [];
let btnClass = "";
if (showPeople) {
btnClass = "Red";
}
if (people.length <= 2) {
assignedClasses.push("red");
}
if (people.length <= 1) {
assignedClasses.push("bold");
}
return (
<div className="Cockpit">
<h1>Hello! Welcome to My Application</h1>
<p className={assignedClasses.join(" ")}>This is application is really great!</p>
<button onClick={clicked} className={btnClass}> Switch to People</button>
<p className={assignedClasses.join(" ")}>Click below link for Debugging!</p>
<button onClick={clicked} className={btnClass}> Click to Launch Debugger</button>
</div>
);
};
export default cockpit;
vii. ErrorBoundary.js
import React, { Component } from "react";
class ErrorBoundary extends Component {
state = {
hasError: false,
errorMessage: ""
};
componentDidCatch = (error, info) => {
this.setState({
hasError: true,
errorMessage: error
});
};
render() {
if (this.state.hasError) {
return <h1>{this.state.errorMessage}</h1>;
} else {
return this.props.children;
}
}
}
export default ErrorBoundary;
viii. People.js
import React from "react";
import Person from "./Person/Person";
import ErrorBoundary from "../ErrorBoundary/ErrorBoundary";
const people = props =>
props.people.map((person, index) => {
return (
<ErrorBoundary key={person.id}>
<Person
click={() => props.clicked(index)}
name={person.name}
age={person.age}
changed={event => props.changed(event, person.id)}
/>
</ErrorBoundary>
);
});
export default people;
ix. Person.css
.Person {
width: 61%;
margin: 17px auto;
border: 2px solid #d1dce8;
box-shadow: 0 3px 4px #7c8894;
padding: 17px;
text-align: center;
}
x. Person.js
import React from "react";
import "./Person.css";
const person = props => { return (
<div className="Person">
<p onClick={props.click}>
My name is {props.name} and I am {props.age} years old!
</p>
<p>{props.children}</p>
<input type="text" onChange={props.changed} value={props.name} />
</div>
);
};
export default person;
xi. App.css
.App {
text-align: center;
}
xii. App.js
import React, { Component } from "react";
import "./App.css";
import People from "../components/People/People";
import Cockpit from "../components/Cockpit/Cockpit";
class App extends Component {
state = {
people: [
{ id: "asfa1"
, name: "Rahul"
, age: 23 },
{ id: "vasdf1"
, name: "Ankush"
, age: 23 },
{ id: "asdf11"
, name: "Adarsh"
, age: 25 }
],
otherState: "some other value",
showPeople: false
};
nameChangedHandler = (event, id) => {
const personIndex = this.state.people.findIndex(p => {
return p.id === id;
});
const person = {
...this.state.people[personIndex]
};
person.name = event.target.value;
const people = [...this.state.people];
people[personIndex] = person;
this.setState({ people });
};
deletePersonHandler = personIndex => {
const people = [...this.state.people];
people.splice(personIndex, 1);
this.setState({ people });
};
togglePeopleHandler = () => {
const doesShow = this.state.showPeople;
this.setState({ showPeople: !doesShow });
};
render() {
const style = { backgroundColor: "#f1ff96",
font: "inherit",
border: "2px #ed85d8",
padding: "9px",
cursor: "pointer"
};
let people = null;
if (this.state.showPeople) {
people = (
<People
people={this.state.people}
clicked={this.deletePersonHandler}
changed={this.nameChangedHandler}
/>
);
}
return (
<div className="App">
<Cockpit
showPeople={this.state.showPeople}
people={this.state.people}
clicked={this.togglePeopleHandler}
/>
{people}
</div>
);
}
}
export default App;
xiii. App.test.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
});
Output:
Conclusion
On the basis of the above discussion, we got to know about what Native Debugger is and how it can be used to debug various applications. The above-mentioned example shows how it works for a particular application.
Recommended Articles
This is a guide to React Native Debugger. Here we discuss the introduction, syntax, and working of React Native Debugger along with code. You can also go through our other related articles to learn more –