Basic React
nurfitri •About React
- React is a javascript library (not a framework like angular).
- We can use react to easily create reactive content in the browser
- We make used of React library and ReactDom.
Create a simple react app
- create a html file called index.html .
- inside that html file, we need to require react library and babel.
- then either in the same index.html file or in a separate .js file we can start writing our react code.
- in this example, I write my jsx code in a file called .index.jsx inside a folder called scripts and include the script inside my html.
<!DOCTYPE html> <html> <head> <!--Here we require react library--> <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin ></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin ></script> <!-- Here we are using babel--> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script> <!--Here I include my external js file--> <script src="/scripts/index.jsx" type="text/babel"></script> </head> <body> <!--we can rename our div #id to anything, but people mostly use root in tutorial--> <div id="root"></div> <div id="second"></div> </body> </html>
- inside our /scripts/index.jsx file, we can create our first react component and then render it to the browser using ReactDOM.
//inside /scripts/index.jsx /* We can rename our component to anything, in other tutorial people sometimes use App. In this example I use Main, but in other in this example I use Main, just to show hat it is possible. */ //to create a react class component, we can extends React.Component class Main extends React.Component{ render(){ return ( <h1>Hello, this is a react app example <h1> ); } } ReactDOM.render(<Main/>,document.querySelector('#root'))
- inside vscode, we can open our index.html with a live server and we can see that our react app is working, with our Main component get rendered on the browser.
- This is however the most basic ways to use React Libraries in our web project.
- There are also other ways to create a react app such as using Create React app Toolchain
Understanding React Component.
In any react App, it mostly consist of components. Components are independent and reusable javascript code that we can use in our app that return a HTML.
In react, there are two types of component:
- Functional Component
- Class Component
In our previous example, we rendered our Main component into the #root div element. Our Main component is a class component. We can declare another class component and render it somewhere else in our html.
<!DOCTYPE html> <html> <head> <!--Here we require react library--> <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin ></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin ></script> <!-- Here we are using babel--> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script> <!--Here I include my external js file--> <script src="/scripts/index.jsx" type="text/babel"></script> </head> <body> <!--we can rename our div #id to anything, but people mostly use root in tutorial--> <div id="root"></div> <div id="second"></div> </body> </html>
inside our index.jsx we can declare a second component and render it on #second div.
// index.jsx class Second extends React.Component { render() { return <h1>Hello I am the second component</h1>; } } class Main extends React.Component { render() { return <h1>Hello World this is react app</h1>; } } ReactDOM.render(<Main />, document.querySelector("#root")); ReactDOM.render(<Second />, document.querySelector("#second"));
- we can also re-used the same component and render it. Instead of rendering <Second/> component on #second div. Here we render two <Main/> components.
// index.jsx class Main extends React.Component { render() { return <h1>Hello World this is react app</h1>; } } ReactDOM.render(<Main />, document.querySelector("#root")); ReactDOM.render(<Main />, document.querySelector("#second"));
What we have done, is equivalent of writing document.createElement and document.appendChild in our vanilla Javascript project. The different is when using React, our code are more cleaner and able to use react library features.
Functional Component example
In the example below, We create the same component as earlier but as functional component.
function Main(){ return ( <h1>Hello, this is a react app example <h1> ) } ReactDOM.render(<Main/>,document.querySelector('#root'));
Note:
- react component only return One element, to return many element, we must nest it inside other html element such as div or react fragment.
/** Example of invalid component returning multiple element **/ function Test(){ // this is invalid return ( <h1> Hello World</h1> <p> something </p> ) } /** Example of valid component returning multiple element **/ function Test2(){ //this is ok!. return ( <div> <h1> Hello World</h1> <p> something </p> </div> ) }
Nesting a component
We can also, nested our component inside another component. In this example, we create a Hello component and render it as a child of our Main component.
function Hello(props) { return <h1>Hello from Hello, {props.children} </h1>; } class Main extends React.Component { render() { return ( <div> This is from Main, <Hello>This is an example of nested component.</Hello> </div> ); } } ReactDOM.render(<Main />, document.querySelector("#root"));
Noticed that props, we used to pass the text from Main component to our Hello component. We will look that props in the next sections.
Reusable component.
By writing components, we allowed our code to be reused multiple times throughout our project. As example, we can create a <button> component with a specific styles and perform actions when clicked.
We can then reused it multiple times in our project without having to re-write the entire styling, and behaviour of a button when clicked.
class Main extends React.Component { showAlert() { alert("Button Clicked!"); } render() { /** here we are re-using the <Button> component with different properties passed to it. **/ return ( <div> This is from Main, <Hello>This is an example of nested component.</Hello> <Button text="Button one" clickHandler={this.showAlert} /> <Button text="Button two" mouseOverHandler={() => { alert("Mouse over me!"); }} /> </div> ); } } function Hello(props) { return <h1> Hello, {props.children}</h1>; } /** Here we declared, a Button component, that accepts few properties such as text, clickHandler, and mouseOverHandler, */ class Button extends React.Component { constructor(props) { super(props); //we bind this so that our method know that this are refered to the class. this.onClickHandler = this.onClickHandler.bind(this); } onClickHandler() { if (typeof this.props.clickHandler == "function") { this.props.clickHandler(); } //do something else console.log("Do something"); } onMouseOverHandler() { if (typeof this.props.mouseOverHandler == "function") { this.props.mouseOverHandler(); } } render() { return ( <button onClick={this.onClickHandler} onMouseOver={this.onMouseOverHandler.bind(this)} > {this.props.text} </button> ); } } ReactDOM.render(<Main />, document.querySelector("#root"));
Understanding Props
Props are properties that we pass between parent and child components to transfer information. A Parent component use props to transfer information to the child component, while child component cannot directly transfer information to parent via props.
Parent -> child (ok) Parent <- child (not ok)
Using the example previously, we create a Button component that accept few properties text,clickHandler,mouseOverHandler. There is no limit on what and how many props we want to share to a component. In above example, we use props to customize the Button components from the parent Main component.
Passing Props
We can provide props from parent to child by passing the value of the properties to our component such as we provide attribute values to a HTML element.
//here we passing propsValue as string <MyComponent attributeName="propsValue" />; //we can alsp pass a variable to the attribute/props key const name = "propsValue"; <MyComponent attributeName={name} />;
To reference or consume the props from child component, we simply get the value of the attributes name from the props variable.
const something = props.attributeName; console.log(attributeName); // print propsValue
props.children
If, you noticed earlier in the nesting a component sections, I used a props named .children to nest element inside of a component element. children is a special react props that we can use to nest element within a component element.
//inside parent component function ParentComp() { return ( <div> The output will be: <ChildComp> Text from parent <GrandChildComp /> </ChildComp> </div> ); } function ChildComp(props) { return <div>Some text from child and {props.children}</div>; } function GrandChildComp(props) { return <div>Some text from grandchild.</div>; } /** The output will be: Some text from parent Some text from child and Text from parent. Some text from grandchild. */
The children props contains the nested element we passed to our child component body. If we passed a string, the children props will containt a type string with the value of the string we passed. In this example, we passed a text and another react component. If we
console.log(props.children);
we will see that it contains an array with string as the first element in the array, and a react.element as the second element.
Props example in Functional Component
function TextContent(props) { const { text } = props; return ( <div> <p>{text}</p> </div> ); } function Main() { const myText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"; return ( <div> <h1> This is header from parent </h1> <TextContent text={myText} /> <TextContent text="Ut enim ad minim veniam, quis nostrud exercitation ullamco" /> </div> ); } ReactDOM.render(<Main />, document.querySelector("#root"));
Props example in Class Component
class TextContent extends React.Component { render() { return ( <div> <p>{this.props.text}</p> </div> ); } } function Main() { const myText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"; return ( <div> <h1> This is header from parent </h1> <TextContent text={myText} /> <TextContent text="Ut enim ad minim veniam, quis nostrud exercitation ullamco" /> </div> ); } ReactDOM.render(<Main />, document.querySelector("#root"));
State in React
What is state in react ? State is an object of observable properties ( a JS object that contains information related to a component that are changing overtime ). Changing the state of a component caused the component to be re-rendered. In Angular if you are familiar, we also can declared a observable properties by using Rxjs. This will create a observable that will observe for changes to a properties and update all the reference of the properties.
In react, we declare a state of our component, the component will then observe the state in the background, and if any we change the property of the state, our view that make use of the state properties will be update (re-render). (this is how I understand it).
few information about react state
- in class component, state is a special named variable.
- in class base component, state can only be updated using the function setState method
- when we update a state, the view will be re-render automatically with the updated state.
- state must be initialized when component is created.
Example of state in Class component.
class Main extends React.Component { //we initialize our state state = { count: 0, }; increaseCounter() { let counter = this.state.count; counter++; /** calling a setState wil change the state value, thus re-render the view with the new state value **/ this.setState({ count: counter, }); } render() { return ( <div> <h1>Counter: {this.state.count}</h1> <button onClick={this.increaseCounter.bind(this)}>increase</button> </div> ); } } ReactDOM.render(<Main />, document.querySelector("#root"));
Example of state in Functional Component.
While in class component we have the state object and setState method to manage the state of our component, in functional component we use a hook instead. A hooks is a special react functions that let us hook into a react state and lifecycle features from a functional component. I will explain more about react hooks later in a separate post.
To manage our state in functional component, we use useState hook.
/* I import the hook like this because I am writing this example in index.jsx file sourced inside index.html using the React library scripts CDN, So the React object already loaded. we can access useState simply by calling the method from the react object like this React.useState(); IF u are following the example from creat-react-app toolchain, you can import hooks using import {useState} from 'React'; */ const { useState } = React; // simply destructuring the React object. function Main() { //here we initialize our state const [count, setCount] = useState(0); function increaseCounter() { const counter = count + 1; //update our counter state setCount(counter); } return ( <div> <h1>Counter: {count}</h1> <button onClick={increaseCounter.bind(this)}>increase</button> </div> ); } ReactDOM.render(<Main />, document.querySelector("#root"));
Component Lifecycle
In react class component, there are few methods that will be executed in stages when a component class get initialized into the DOM. These methods are called lifecycle methods, and one of the method we saw earlier is the render() method.
We can make use of these methods whenever we want to perform specific actions on a specific stage of our component lifecycle.
React component Lifecycle
There are 3 main stages of react component lifecycle.
- mounting
- updating
- unmounting.
Mounting
Mounting happen when the web page is loaded by the browser. Our browser load all the javascript file and then create the component that we declared. As a component get initialized these methods get called in an order:
constructor() -> componentWillMount() -> render() ->componentDidMount().
Updating
Updating happen when we make changes to our component states via setState method or the useState hook. When we update the state, our component get re-render by the browser and called these methods in an order:
componentWillUpdate() -> render() -> componentDidUpdate()
Unmounting
Unmounting happens when the component are no longer being used and get detached from the DOM. (no longer showing on the page). When component unmounting it will call the componentWillUnmount() method.
Note:
- componentWillUpdate and componentWillMount is not recommended to be use
- people no longer use these two methods. refer here
- I included this information just for the purpose of demo and education.
React Lifecycle example
class Main extends React.Component{ constructor(props){ super(props); this.state = { haveJob : 'false' } console.log('inside constructor'); } componentWillMount(){ console.log('after constructor'); } render(){ console.log('inside render') return ( <div> <p>Do I have a Job? : {this.state.haveJob}</p> {{ this.state.haveJob == 'false' && <button onClick={()=>this.setState({haveJob:'true'})}> Get a job </button> }} </div> ) } componentDidMount(){ console.log('after render'); } componentWillUpdate(){ console.log("State will update"); } componentDidUpdate(){ const state = this.state.haveJob; console.log('state updated to:',state); } } ReactDOM.render(<Main/>,document.querySelector('#root'));
Conclusion
This is probably the most basic stuff you need to know about React. There are more to it that we can learn about react, such as Redux,Router,hooks,context and more.