ReactJS: Chuck Norris Jokes App
Create a Chuck Norris App using ReactJS
Note that he number of jokes displayed can be altered using the dropdown list.
Create a new repl uing the plain React template (not the TS or Reason ones). Not all the standard files are needed, so delete some of them using the screenshot below to guide you. Change the name of App.css to App.module.css so CSS modules can be used to scope specific styles to the App component. Visit the following link to read more about CSS modules: https://programmingwithmosh.com/react/css-modules-react/
After the app has automatically started (it takes a little while and the web page may need to be reloaded), errors will be present in App.js and index.js. Correct these by removing references to the files that have been deleted.
Edit the code in App.js so it is the same as in the screenshot below.
Note that the default App class has been changed into a function. Using functional components, rather than class based ones, is the recommended way to program in React.
The useEffect and useState hooks have to be imported so edit the import line at the top of the file so it is the same as the code below.
The useState function is used to store the app's state, which is the array of jokes and the number of jokes to be displayed. useEffect is used to load the jokes from the API endpoint when the App starts and whenever a new number of jokes is chosen using the dropdown. Edit App.js's code so it is the same as that seen in the screenshot below.
Read this article if you do not know about hooks: https://www.valentinog.com/blog/hooks/
Now is the time to add some styling to the App. Inside of App.module.css edit the code so it is the same as that seen below.
The CSS has to be imported into App. The screenshot below shows how to do this. Note that the imported styles has been assigned the name styles . This can now be used to assign styles using classes to the HTML elements in App.js, it also allows for the direct styling of standard HTML elements (e.g. main, p, h1) without having to use the styles keyword.
To apply the container styles to the div that contains the app, change the following line in the App js file:
Edit the code in App.js so it is the same as that seen below.
There is quite a lot to explain about this code.
The useEffect hook function has two parameters:
- The first is a function that will run when useEffect is called. As mentioned above, this happens when the App componentis added to the web page's DOM, and on any change in the number of jokes chosen.
- The second is an array that holds values that are "watched". When they change useEffect will run again. In the screenshot it can be seen that the function parameter is an anonymous arrow function . This function uses the JS fetch function to load data from the JSON endpoint:
Note that numJokes is tacked onto the end to ask for a specific number of jokes. If you visit https://api.icndb.com/jokes/random/3 with your browser address, you will see the JSON for 3 random jokes. Here is what it looks like (click on the image to see a bigger version).
The JSON that is returned contains an array called value and each element of value is an object literal that has three keys - id , joke and catergories . We will use id and joke, but not categories. Once the JSON is returned by the value array can be looped through and the id and joke keys can be used to create strings of HTML that is then injected into the web page. Note that the second parameter is an array containing the numJokes variable. When this changes e.g. when the user selects a different of jokes, useEffect will run.
We are almost at the point where 5 quotes are displayed. Edit your code so it is the same as that seen in the screenshot below.
Now update the CSS styling by editing the code in App.module.css so it is the same as ther code seen in the screenshot below.
The app should run correctly at this point in that five jokes (the value of numJokes) are displayed. You can stop at this point or carry on to enhance the app by allowing the user to choose how many quotes to see. Edit App.js so your code is the same as that seen in the screenshot below. A select element has been added and a function called updateNumJokes has been set to be called whenever there is a change triggered by selecting another option.
The app will break at this stage because React does not know about the function called updateNumJokes. Edit the App.js code to add the function. Use the following code:
evt is the event object that is passed to the function when the function is triggered. It can be used to find which option has been chosen as evt.target.value holds the value of the option chosen (e.g. "5", "10", "15" or "20")
parseInt takes a string and attempts to turn it into the corresponding integer. The number 10 is an optional parameter that can be used to specify the number system being used. In this case it's decimal, which is 10 based.
The setNumJokes function will update the value of numJokes. Since this is being watched by useEffect it will run again, fetching the required number of jokes. These will then be re-rendered as React re-renders whenever a change in state occurs.
You may notice that quotes within the jokes are displaying as HTML entities rather than double or single quotes. To fix this a function called dangerouslySetInnerHTML has to be used. Create a function called getContent and add the code seen in the screenshot below to it (click on the image to see a larger version). Note that:
- The array created by using map is immediately returned; and a key attribute is added to each paragraph. This is needed by React to manage lists of similar items.
Next edit the code in App.js so it matches that seen in the screenshot below.
Test the app.
Find a picture of Chuck Norris and then add it to the files list in your repl. The one used in the example app was found using this query string
Import the image into App.js. For example, if the image is called chuck.png this is how to import it. Note that chuck is the name assigned to the image on import:
Add an image tag underneath the H1 tag in App.js and using the assigned name (chuck) add a source attribute, like so:
The app should be now be fully functioning. Here is a link to the completed repl: https://repl.it/@malvoliothegood/Chuck-app-in-progress
Comment if you have any questions.