Dr. Greg Bernstein
Updated September 17th, 2021
Can return JSX expressions from a function Components and Props:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
If our function begins with a capital letter and returns JSX, React will interpret this as a component!
These have a similar feel to custom HTML elements
Attributes of the component get fed to the function via props
Example branch funcComp1
import React from 'react';
import ReactDOM from 'react-dom';
// Function Component Definition
function Welcome(props) { // Start with Capital
return <h1> Hello, {props.name} </h1>; // returns JSX
}
// Function component use -- looks like custom HTML
let contents = <section>
<Welcome name="Web Development" />
<Welcome name="Dr. B" />
</section>;
ReactDOM.render(contents,
document.getElementById('root')
);
<Welcome>
tag in HTML, this is our own component<Welcome name="Web Development" />;
name
attribute gets sent into the component function as a field of the props
argument.props
as read-only. Do not write to them ever!A web app for students to test themselves on HTML, CSS, and JavaScript.
Will build in pieces from React components testing as we go
Will start with a JSON file as our question pool instead of a database.
From branch funcComp2
. Each multiple choice question has three fields: question (text), choices (array), answer (integer):
{ "question": "Which is an example of a class selector?",
"choices": ["p", "section > p", "#ThisThing", ".error"],
"answer": 3},
{ "question": "Which is an example of an id selector?",
"choices": ["p", "section > p", "#ThisThing", ".error"],
"answer": 2 },
First Step (branch funcComp2
) display question portion of a multiple choice test:
import React from 'react';
import ReactDOM from 'react-dom';
import questions from './questions.json';
function randInt(max){
return Math.floor(Math.random()* Math.floor(max));}
// Start of Question Component
function Question(props) {
return <p>{props.multiChoice.question}</p>;
}
let mChoice = questions[randInt(questions.length)];
let contents = <div><h1>Quiz-o-Matic</h1>
<Question multiChoice={mChoice} />
</div>;
ReactDOM.render(contents, document.getElementById('root'));
Let’s use the JavaScript array.map() function to generate an array of JSX list items.
Let’s style the list to use the usual a., b., c., etc… for enumerating the choices. Style it with list-style-type: "lower-alpha";
Don’t forget to use the React key
attribute! keys only need to be unique within the array, they are not ids
map()
From Array.map()
var new_array = arr.map(callback)
The callback function receives three arguments:
function Choices(props) {
// Creates an array of list item JSX elements with key
let listItems = props.choices.map(function(choice, i) {
return <li key={"choice" + i}>{choice}</li>;});
// Set some styling on the list note that
// list-style-type becomes listStyleType
let choiceStyle = {listStyleType: "lower-alpha"};
return <ol style={choiceStyle}>
{listItems}
</ol>;
}
We will have the Question component now contain the Choices component.
Recall the structure of a multiple choice question object:
mChoiceQuest = {question: "stuff",
choices: ["array", "of", "choices"]
answer: 0}
function Question(props) {
return <div>
<p>{props.multiChoiceQ.question}</p>
<Choices choices={props.multiChoiceQ.choices} />
</div>;
}
let mChoice = questions[randInt(questions.length)];
let contents = <div><h1>Quiz-o-Matic</h1>
<Question multiChoiceQ={mChoice} />
</div>;
ReactDOM.render(
contents,
document.getElementById('root')
);
Move the Question component into its own module question.js
(branch funcComp3
):
import React from 'react';
function Choices(props) {
// Creates an array of list item JSX elements with key
let listItems = props.choices.map(function(choice, i) {
return <li key={"choice" + i}>{choice}</li>;});
// Set some styling on the list note that
// list-style-type becomes listStyleType
let choiceStyle = {listStyleType: "lower-alpha"};
return <ol style={choiceStyle}>
{listItems}
</ol>;
}
function Question(props) {
return <div>
<p>{props.multiChoiceQ.question}</p>
<Choices choices={props.multiChoiceQ.choices} />
</div>;
}
export default Question;
index.js
branch funcComp3
import React from 'react';
import ReactDOM from 'react-dom';
import Question from './question'; // ES6 module import!
import './index.css';
import questions from './questions.json';
// Let's look at all the questions
let allQs = questions.map(function(mChoice, i){
return <Question key={"q" + i} multiChoiceQ={mChoice} />
})
let contents = <div><h1>Quiz-o-Matic</h1>{allQs}</div>;
ReactDOM.render(
contents,
document.getElementById('root')
);