Learning React in 20 hours: 2nd attempt
Day 1: The first 2 hours(28th March 2020)
This article in its current state is not meant as a tutorial on react. It is collection of notes I took while learning React. This is my way of keeping a log of what I learnt. This article will help me easily pick up the concepts I learn in the past.
The first time I learn React, I prepared some notes but lost them. When I tried to recall what I had learnt, I drew a blank and since I had no notes to refer to, I had to relearn everything from scratch.
I decided to have another go at React after testing a little bit on Vue.
Choosing learning materials
I researched for a selection of tutorials to follow along. I settled on two tutorials that seemed reasonable to me at the time:
I decided to first try the React’s official Tic-tac-toe project based tutorial.
Installating Create-React-App
It took me about 15-20 minutes to install a create react app project.
I used the following command to install this app.
npx create-react-app react-tutorial-2 cd react-tutorial-2 yarn start
After the last command, I got the following notification on the terminal:
You can now view react-tutorial-2 in the browser. Local: http://localhost:3000 On Your Network: http://192.168.43.11:3000
I entered the url on the browser and the react project was live.
Components in React
React is used to build user interfaces UI’s. You can build complex UI’s by building small parts called components.
There are different kind of components
- 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" />
Components tell react what it should show on screen/ display.
A component takes in parameters, called props (short for “properties”), and returns a hierarchy of views to display via the render method.( I have no Idea what this means at this particular time).
The render method returns a description of what you want to see on the screen. React takes the description and displays the result.
Each React component is encapsulated and can operate independently; this allows you to build complex UIs from simple components.
Starter code for Tic-tac-toe app
Delete files inside src by:
rm -f * touch index.js index.css
Copy starter code for index.js and index.css
Inspecting the code, you’ll notice that we have three React components:
-
- Square
- Board
- Game
They have this syntax:
class Square extends React.Component { render() { return ( ) } }
Passing a props from parent to child
Parent:
class Board extends React.Component { renderSquare(i) { return <Square value={i} />; }
Child:
class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }
Passing props is how information flows in React apps, from parents to children.
Click event handler:
<button className="square" onClick={()=>{alert("clicked")}}> {this.props.value} </button>
React’s component State memory
Components use state to remember what has happened.
React components can have state by setting this.state in their constructors. this.state should be considered as private to a React component that it’s defined in.
class Square extends React.Component { constructor(props){ super(props); this.state= { value:null }; } render() { return ( <button className="square" onClick={()=>{alert("clicked")}}> {this.props.value} </button> ); } }
Finally instead of alert, let there be an X inside the square.
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}
render() {
return (
<button
className="square"
onClick={() => this.setState({value: 'X'})}>
{this.state.value}
</button>
);
}
}
By calling this.setState from an onClick handler in the Square’s render method, we tell React to re-render that Square whenever its <button>
is clicked. After the update, the Square’s this.state.value will be ‘X’, so we’ll see the X on the game board. If you click on any Square, an X should show up.
When you call setState in a component, React automatically updates the child components inside of it too.
In JavaScript classes, you need to always call super when defining the constructor of a subclass. All React component classes that have a constructor should start with a super(props) call.
Personal Practice project
I practiced practice making simple components on personal project. You can see the code here.
Day 2: Reacts props and state
Data is handled using properties(props) and state
Create an array of objects that will contain the data to be added to the table.
This data should go to the most top level component.
class App extends React.Component {
render() {
const characters = [
{
name: "Character",
job: "Janitor"
},
{
name: "Mac",
job: "Bouncer"
}
]
return (
<div className="app">
<Table />
<NewTable />
</div>
)
}
}
Pass the data to the child component (Table) with properties.
Give the property a name: characterData
<NewTable characterData={characters}/>
Accessing the data on the child NewTable
const { characterData } = this.props
Pass the data to the child TableBody
<TableBody characterData= {characterData}/>
Lets pass the headings of the table as props
- Create an object in App component
const tableHeadings = { column1: "Name", column2: "Job" }
- Pass it to the child component Table
<Table tableHeadings= { tableHeadings }/>
- Render the component in the table heading
const {tableHeadings} = this.props <thead> <tr> <th>{ tableHeadings.column1 }</th> <th>{ tableHeadings.column2 }</th> </tr> </thead>
15:47
// create the data value that you want to keep track of in state
state ={ count: 0 }
// create a callback function in the parent component
countKeeper = (childCount) => {
this.setState({count: childCount})
}
Pass it as a props to the child Navbar
<Navbar
parentCallback = {this.callbackFunction}
parentCountKeeper = {this.countKeeper}
/>
in the child
sendCount = ()=> {
this.props.parentCountKeeper(10);
}
add a button to call this function
<button className="button" onClick={()=> this.sendCount()}> Button</button>
This should modify the value of count on parent
You can read more here.
Full example:
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; // react pass data from parent to child // Good solutions https://guide.freecodecamp.org/certifications/front-end-libraries/react/pass-state-as-props-to-child-components/ // Good explanation: https://www.freecodecamp.org/forum/t/react-pass-state-as-props-to-child-components/202933/4 // react pass data back from child to parent // create the data value that you want to keep track of in state // i.e. count: 0 // create a callback function in the parent component class App extends React.Component { constructor(props){ super(props); this.state={ message: "", count:0 } } countKeeper = (childCount) => { this.setState({count: childCount}) } callbackFunction = (childData) => { this.setState({message: childData}) }; render() { return ( <div> <Navbar parentCallback = {this.callbackFunction} parentCountKeeper = {this.countKeeper} count= {this.state.count} /> <p> {this.state.message} </p> <p> {this.state.count}</p> </div> ); } }; class Navbar extends React.Component { sendData = () => { this.props.parentCallback("Hey Popsie, How’s it going?"); }; sendCount = ()=> { this.props.parentCountKeeper(5 ); } render() { return( <div className="header"> <h1 id="my-logo" className="title">Picture learner</h1> <button className="button" onClick={(e)=> this.sendData(e)}>Button</button> <button className="button" onClick={()=> this.sendCount()}>Button</button> <p> {this.props.count}</p> </div> ) //you can call function sendData whenever you'd like to send data from child component to Parent component. } }; ReactDOM.render(<App />, document.getElementById('root'))
Refactoring picture learner
Create new component
class CycleButtons extends Component { render(){ return( <div> <button className="button" onClick={(e)=> this.decrement(e)}>Previous</button> <button className="button" onClick={(e)=> this.increment(e)}>Next</button> </div> ) } } Add this in Items component <CycleButtons />