All of the code examples below will be included a second time at the bottom of this article as an embedded gist.
Introduction to React for Complete Beginners
All of the code examples below will be included a second time at the bottom of this article as an embedded gist, so that it is properly syntax highlighted.
React uses a syntax extension of JavaScript called JSX that allows you to write HTML directly within JavaScript.
React
React uses a syntax extension of JavaScript called JSX that allows you to write HTML directly within JavaScript
because JSX is a syntactic extension of JavaScript, you can actually write JavaScript directly within JSX
include the code you want to be treated as JavaScript within curly braces: { 'this is treated as JavaScript code' }
JSX code must be compiled into JavaScript
under the hood the challenges are calling ReactDOM.render (JSX, document.getElementById('root'))
One important thing to know about nested JSX is that it must return a single element.
For instance, several JSX elements written as siblings with no parent wrapper element will not transpile.
From the React Docs:
What is React?
React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It lets you compose complex UIs from small and isolated pieces of code called “components”.
React has a few different kinds of components, but we'll start with React.Component subclasses:
class ShoppingList extends React.Component {
render() {
return (
<div className="shopping-list">
<h1>Shopping List for {this.props.name}</h1>
<ul>
<li>Instagram</li>
<li>WhatsApp</li>
<li>Oculus</li>
</ul>
</div>
);
}
}
// Example usage: <ShoppingList name="Mark" />
We'll get to the funny XML-like tags soon. We use components to tell React what we want to see on the screen. When our data changes, React will efficiently update and re-render our components.
Here, ShoppingList is a React component class, or React component type. A component takes in parameters, called props (short for “properties”), and returns a hierarchy of views to display via the render method.
The render method returns a description of what you want to see on the screen. React takes the description and displays the result. In particular, render returns a React element, which is a lightweight description of what to render. Most React developers use a special syntax called “JSX” which makes these structures easier to write. The <div /> syntax is transformed at build time to React.createElement('div'). The example above is equivalent to:
return React.createElement('div', {className: 'shopping-list'},
React.createElement('h1', /* ... h1 children ... */),
React.createElement('ul', /* ... ul children ... */)
);
To put comments inside JSX, you use the syntax {/* */} to wrap around the comment text.
To put comments inside JSX, you use the syntax {/* */} to wrap around the comment text.
The code editor has a JSX element similar to what you created in the last challenge. Add a comment somewhere within the provided div element, without modifying the existing h1 or p elements.
const JSX = (
<div>
{/* This is a comment */}
<h1>This is a block of JSX</h1>
<p>Here's a subtitle</p>
</div>
);
With React, we can render this JSX directly to the HTML DOM using React's rendering API known as ReactDOM.
ReactDOM offers a simple method to render React elements to the DOM which looks like this:
ReactDOM.render(componentToRender, targetNode)
the first argument is the React element or component that you want to render,
and the second argument is the DOM node that you want to render the component to.
ReactDOM.render() must be called after the JSX element declarations, just like how you must declare variables before using them.
key difference in JSX is that you can no longer use the word class to define HTML classes.
— -> This is because class is a reserved word in JavaScript. Instead, JSX uses className
the naming convention for all HTML attributes and event references in JSX become camelCase
a click event in JSX is onClick, instead of onclick. Likewise, onchange becomes onChange. While this is a subtle difference, it is an important one to keep in mind moving forward.
Apply a class of myDiv to the div provided in the JSX code.
The constant JSX should return a div element.
The div should have a class of myDiv.
const JSX = (
<div>
<h1>Add a class to this div</h1>
</div>
);
Ans:
const JSX = (
<div className="myDiv">
<h1>Add a class to this div</h1>
</div>
);
React: Learn About Self-Closing JSX Tags
-Another important way in which JSX differs from HTML is in the idea of the self-closing tag.
In HTML, almost all tags have both an opening and closing tag:<div></div>;the closing tag always has a forward slash before the tag name that you are closing.
there are special instances in HTML called “self-closing tags”, or tags that don't require both an opening and closing tag before another tag can start.
For example the line-break tag can be written as<br>or as<br />,but should never be written as<br></br>, since it doesn't contain any content.
In JSX, the rules are a little different. Any JSX element can be written with a self-closing tag, and every element must be closed.The line-break tag, for example, must always be written as<br />in order to be valid JSX that can be transpiled.A<div>, on the other hand, can be written as<div />or<div></div>.The difference is that in the first syntax version there is no way to include anything in the<div />.
Fix the errors in the code editor so that it is valid JSX and successfully transpiles. Make sure you don't change any of the content — you only need to close tags where they are needed.
const JSX = (
<div>
<h2>Welcome to React!</h2> <br >
<p>Be sure to close all tags!</p>
<hr >
</div>
);
Ans:
const JSX = (
<div>
<h2>Welcome to React!</h2> <br />
<p>Be sure to close all tags!</p>
<hr />
</div>
);
React: Create a Stateless Functional Component
There are two ways to create a React component. The first way is to use a JavaScript function.
Defining a component in this way creates a stateless functional component.
think of a stateless component as one that can receive data and render it, but does not manage or track changes to that data.
To create a component with a function, you simply write a JavaScript function that returns either JSX or null
React requires your function name to begin with a capital letter.
Here's an example of a stateless functional component that assigns an HTML class in JSX:
// After being transpiled, the <div> will have a CSS class of 'customClass'
const DemoComponent = function() {
return (
<div className='customClass' />
);
};
Because a JSX component represents HTML, you could put several components together to create a more complex HTML page.
The code editor has a function called MyComponent. Complete this function so it returns a single div element which contains some string of text.
Note: The text is considered a child of the div element, so you will not be able to use a self-closing tag.
const MyComponent = function() {
// Change code below this line
// Change code above this line
}
ANS:
const MyComponent = function() {
// Change code below this line
return (
<div> Some Text </div >
);
// Change code above this line
};
React: Create a React Component
The other way to define a React component is with the ES6 class syntax. In the following example, Kitten extends React.Component:
This creates an ES6 class Kitten which extends the React.Component class.
So the Kitten class now has access to many useful React features, such as local state and lifecycle hooks.
Also notice the Kitten class has a constructor defined within it that calls super()
It uses super() to call the constructor of the parent class, in this case React.Component
The constructor is a special method used during the initialization of objects that are created with the class keyword. It is best practice to call a component's constructor with super, and pass props to both.
This makes sure the component is initialized properly. For now, know that it is standard for this code to be included.
MyComponent is defined in the code editor using class syntax. Finish writing the render method so it returns a div element that contains an h1 with the text Hello React!.
class MyComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
// Change code below this line
// Change code above this line
}
};
ANS:
class MyComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
// Change code below this line
return (
<div>
<h1>Hello React!</h1>
</div>
);
// Change code above this line
}
};
React: Create a Component with Composition
Imagine you are building an App and have created three components, a Navbar, Dashboard, and Footer.
To compose these components together, you could create an App parent component which renders each of these three components as children. To render a component as a child in a React component, you include the component name written as a custom HTML tag in the JSX.
For example, in the render method you could write:
When React encounters a custom HTML tag that references another component (a component name wrapped in < /> like in this example), it renders the markup for that component in the location of the tag. This should illustrate the parent/child relationship between the App component and the Navbar, Dashboard, and Footer.
Challenge:
In the code editor, there is a simple functional component called ChildComponent and a class component called ParentComponent. Compose the two together by rendering the ChildComponent within the ParentComponent. Make sure to close the ChildComponent tag with a forward slash.
Note:ChildComponent is defined with an ES6 arrow function because this is a very common practice when using React.
However, know that this is just a function.
const ChildComponent = () => {
return (
<div>
<p>I am the child</p>
</div>
);
};
class ParentComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>I am the parent</h1>
{ /* Change code below this line */ }
{ /* Change code above this line */ }
</div>
);
}
};
⌛The React component should return a single div element.
⌛The component should return two nested elements.
⌛The component should return the ChildComponent as its second child.
Ans:
const ChildComponent = () => {
return (
<div>
<p>I am the child</p>
</div>
);
};
class ParentComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>I am the parent</h1>
{ /* Change code below this line */ }
{ /* Change code above this line */ }
</div>
);
}
};
Use the useState() hook to create the isShown and isLeaving state variables and set both to false initially.
Define timeoutId to keep the timer instance for clearing on component unmount.
Use the useEffect() hook to update the value of isShown to true and clear the interval by using timeoutId when the component is unmounted.
Define a closeAlert function to set the component as removed from the DOM by displaying a fading out animation and set isShown to false via setTimeout().
constForm= () => {const [value,setValue] =React.useState("");return (<ControlledInputtype="text"placeholder="Insert some text here..."value={value}onValueChange={setValue}/>);};ReactDOM.render(<Form />,document.getElementById("root"));
Renders a countdown timer that prints a message when it reaches zero.
Use the useState() hook to create a state variable to hold the time value, initialize it from the props and destructure it into its components.
Use the useState() hook to create the paused and over state variables, used to prevent the timer from ticking if it's paused or the time has run out.
Create a method tick, that updates the time values based on the current value (i.e. decreasing the time by one second).
Create a method reset, that resets all state variables to their initial states.
Use the the useEffect() hook to call the tick method every second via the use of setInterval() and use clearInterval() to clean up when the component is unmounted.
Use String.prototype.padStart() to pad each part of the time array to two characters to create the visual representation of the timer.
Renders a file drag and drop component for a single file.
Create a ref, called dropRef and bind it to the component's wrapper.
Use the useState() hook to create the drag and filename variables, initialized to false and '' respectively.
The variables dragCounter and drag are used to determine if a file is being dragged, while filename is used to store the dropped file's name.
Create the handleDrag, handleDragIn, handleDragOut and handleDrop methods to handle drag and drop functionality.
handleDrag prevents the browser from opening the dragged file, handleDragIn and handleDragOut handle the dragged file entering and exiting the component, while handleDrop handles the file being dropped and passes it to onDrop.
Use the useEffect() hook to handle each of the drag and drop events using the previously created methods.
Use the useState() hook to create a state variable, containing content and wordCount, using the value prop and 0 as the initial values respectively.
Use the useCallback() hooks to create a memoized function, setFormattedContent, that uses String.prototype.split() to turn the input into an array of words.
Check if the result of applying Array.prototype.filter() combined with Boolean has a length longer than limit and, if so, trim the input, otherwise return the raw input, updating state accordingly in both cases.
Use the useEffect() hook to call the setFormattedContent method on the value of the content state variable during the initial render.
Bind the onChange event of the <textarea> to call setFormattedContent with the value of event.target.value.
Renders a link formatted to send an email (mailto: link).
Use the email, subject and body props to create a <a> element with an appropriate href attribute.
Use encodeURIcomponent to safely encode the subject and body into the link URL.
Render the link with children as its content.
constMailto= ({ email, subject ="", body ="", children }) => {let params = subject || body ?"?" :"";if (subject) params +=`subject=${encodeURIComponent(subject)}`;if (body) params +=`${subject ?"&" :""}body=${encodeURIComponent(body)}`;return <a href={`mailto:${email}${params}`}>{children}</a>;};
ReactDOM.render(<Mailto email="foo@bar.baz" subject="Hello & Welcome" body="Hello world!"> Mail me!</Mailto>,document.getElementById("root"));
Renders a table with rows dynamically created from an array of objects and a list of property names.
Use Object.keys(), Array.prototype.filter(), Array.prototype.includes() and Array.prototype.reduce() to produce a filteredData array, containing all objects with the keys specified in propertyNames.
Render a <table> element with a set of columns equal to the amount of values in propertyNames.
Use Array.prototype.map() to render each value in the propertyNames array as a <th> element.
Use Array.prototype.map() to render each object in the filteredData array as a <tr> element, containing a <td> for each key in the object.
This component does not work with nested objects and will break if there are nested objects inside any of the properties specified in propertyNames
Renders a checkbox list that uses a callback function to pass its selected value/values to the parent component.
Use the useState() hook to create the data state variable and use the options prop to initialize its value.
Create a toggle function that uses the spread operator (...) and Array.prototype.splice() to update the data state variable and call the onChange callback with any checked options.
Use Array.prototype.map() to map the data state variable to individual <input type="checkbox"> elements, each one wrapped in a <label>, binding the onClick handler to the toggle function.
Renders a button that animates a ripple effect when clicked.
Use the useState() hook to create the coords and isRippling state variables for the pointer's coordinates and the animation state of the button respectively.
Use a useEffect() hook to change the value of isRippling every time the coords state variable changes, starting the animation.
Use setTimeout() in the previous hook to clear the animation after it's done playing.
Use a useEffect() hook to reset coords whenever the isRippling state variable is false.
Handle the onClick event by updating the coords state variable and calling the passed callback.
Define a component, called Star that will render each individual star with the appropriate appearance, based on the parent component's state.
In the StarRating component, use the useState() hook to define the rating and selection state variables with the appropriate initial values.
Create a method, hoverOver, that updates selected according to the provided event, using the .data-star-id attribute of the event's target or resets it to 0 if called with a null argument.
Use Array.from() to create an array of 5 elements and Array.prototype.map() to create individual <Star> components.
Handle the onMouseOver and onMouseLeave events of the wrapping element using hoverOver and the onClick event using setRating.
Define a Tabs component that uses the useState() hook to initialize the value of the bindIndex state variable to defaultIndex.
Define a TabItem component and filter children passed to the Tabs component to remove unnecessary nodes except for TabItem by identifying the function's name.
Define changeTab, which will be executed when clicking a <button> from the menu.
changeTab executes the passed callback, onTabClick, and updates bindIndex based on the clicked element.
Use Array.prototype.map() on the collected nodes to render the menu and view of the tabs, using the value of binIndex to determine the active tab and apply the correct className.
Define a TagInput component and use the useState() hook to initialize an array from tags.
Use Array.prototype.map() on the collected nodes to render the list of tags.
Define the addTagData method, which will be executed when pressing the Enter key.
The addTagData method calls setTagData to add the new tag using the spread (...) operator to prepend the existing tags and add the new tag at the end of the tagData array.
Define the removeTagData method, which will be executed on clicking the delete icon in the tag.
Use Array.prototype.filter() in the removeTagData method to remove the tag using its index to filter it out from the tagData array.
ReactDOM.render(<TextArea placeholder="Insert some text here..." onValueChange={(val) => console.log(val)}/>,document.getElementById("root"));
Renders a toggle component.
Use the useState() hook to initialize the isToggleOn state variable to defaultToggled.
Render an <input> and bind its onClick event to update the isToggledOn state variable, applying the appropriate className to the wrapping <label>.
ReactDOM.render(<UncontrolledInput type="text" placeholder="Insert some text here..." onValueChange={console.log}/>,document.getElementById("root"));
Handles asynchronous calls.
Create a custom hook that takes a handler function, fn.
Define a reducer function and an initial state for the custom hook's state.
Use the useReducer() hook to initialize the state variable and the dispatch function.
Define an asynchronous run function that will run the provided callback, fn, while using dispatch to update state as necessary.
Return an object containing the properties of state (value, error and loading) and the run function.
Checks if the current environment matches a given media query and returns the appropriate value.
Check if window and window.matchMedia exist, return whenFalse if not (e.g. SSR environment or unsupported browser).
Use window.matchMedia() to match the given query, cast its matches property to a boolean and store in a state variable, match, using the useState() hook.
Use the useEffect() hook to add a listener for changes and to clean up the listeners after the hook is destroyed.
Return either whenTrue or whenFalse based on the value of match.
constStatusIndicator= () => {constisOnline=useNavigatorOnLine();return<span>You are {isOnline ?"online" :"offline"}.</span>;};ReactDOM.render(<StatusIndicator />,document.getElementById("root"));
Returns a stateful value, persisted in localStorage, and a function to update it.
Use the useState() hook to initialize the value to defaultValue.
Use the useRef() hook to create a ref that will hold the name of the value in localStorage.
Use 3 instances of the useEffect() hook for initialization, value change and name change respectively.
When the component is first mounted, use Storage.getItem() to update value if there's a stored value or Storage.setItem() to persist the current value.
When value is updated, use Storage.setItem() to store the new value.
When name is updated, use Storage.setItem() to create the new key, update the nameRef and use Storage.removeItem() to remove the previous key from localStorage.
NOTE: The hook is meant for use with primitive values (i.e. not objects) and doesn't account for changes to localStorage due to other code. Both of these issues can be easily handled (e.g. JSON serialization and handling the 'storage' event).