Monday, November 29, 2021

Ninja - React Basic 11 - Reuse Components

Let's reuse this componet we use. We already use to show the values in the 'blogs'

Now we need to show the values filter by author='mario'

let's see how are going to use this.


1. let's create a new div tag below.

<BlogList blogs={blogs} title="Mario's Blogs"/>

2. we can use filter

<BlogList blogs={blogs.filter()} title="Mario's Blogs"/>

3. Then, this filter method will call a call back function for each otem in  the array

<BlogList blogs={blogs.filter(  ()= {} )} title="Mario's Blogs"/>


a.) if true keeps in the array

b.) if false, filters outof the array

c.) and return new array with only filtered true values



4. Then passing that 'data' as a  prop.


if we show the original data


const [blogs, setBlogs] = useState([

        { title: 'My new website', body: 'lorem ipsum...', author: 'mario', id: 1 },

        { title: 'Welcome party!', body: 'lorem ipsum...', author: 'yoshi', id: 2 },

        { title: 'Web dev top tips', body: 'lorem ipsum...', author: 'mario', id: 3 }

    ]);

5. take 'blog' as arguemnt for filter

<BlogList blogs={blogs.filter(  (blogs)= {} )} title="Mario's Blogs"/>

6. check author=mario

<BlogList blogs={blogs.filter( (blog) => blog.author==='mario' )} title="Mario's Blogs"/>

Ninja - React Basic 10 - Props

Let's look at scenario where we have blogs in each page as we did it in Home page. Then we need to repeat the code block in every page.  

How to do it in a more better way.

we can make that bit of template as resusable component. eg: blog list component


{blogs.map(((blog) => (

                <div className='blog-preview' key={blog.id}>

                    <h2>{blog.title}</h2>

                    <p>Written by {blog.author}</p>

                </div>

            )))}


So if need to use that part in a category, tag or in any place we can just drop our component 'blog-list'.  We don't  need to repeat this total boiler plate code.


We use 'props'

with this template or component will be same, but data will be different. This helps to reuse.


1. create blog list component to hold the logic

2. create file 'BlogList.js' and create component BlogList


const BlogList = () => {

    return ();

}


export default BlogList;


3. Inside return copy paste the template we a re going to reuse. 

4. Before that let's  create a div , className=blog-list


const BlogList = () => {

    return (

        <div className='blog-list'>

            {blogs.map(((blog) => (

                <div className='blog-preview' key={blog.id}>

                    <h2>{blog.title}</h2>

                    <p>Written by {blog.author}</p>

                </div>

            )))}

        </div>

    );

}


5. Now inside home.js , we can simply use <BlogList />


return (

        <div className="home">

            <BlogList />

        </div>

    );


6. Now you get an error

'blogs' is not defined  no-undef


7. Because blogs data is not defined inside BlogList, we cannot use data defined inside another component.

8. How to solve ? There are few solutions.

8.1 Define data inside BlogList instead of Home

8.2 Use Props -> we pass this data from Home component into the BlogList component. 

9. We use second option props for three reasons


a. make BlogList component more resusable

b. We can still use data in the Home component, if needed inside Home component

c. Most important -> How to use props


10. Props is a way to pass data from a parent component to child component

11. Here Home is the parent and BlogList is the Child component

12. we are passing 'blogs' data into BlogList component

13. To do that, we create a property inside the <BlogList /> tag. You can call any name. Let's call 'blogs' as it's what we are passing.

<BlogList blogs= />

14. So this going to be a dynamic value, So curly braces.

<BlogList blogs={} />

15. value is 'blogs'. defined in top of the Home component.  

<div className="home">

            <BlogList blogs={blogs} />

 </div>

16. Now this is a prop. Now you will see an error

src\component\BlogList.js

  Line 4:14:  'blogs' is not defined  no-undef

  

17. This is cause of the next step, we are now going to use in BlogList. give tis as a parameter to BlogList


const BlogList = (blogs) => {

    return (

        <div className='blog-list'>

            {blogs.map(((blog) => (

                <div className='blog-preview' key={blog.id}>

                    <h2>{blog.title}</h2>

                    <p>Written by {blog.author}</p>

                </div>

            )))}

        </div>

    );

}


18. Now your error will disapear

19. Now we have another error


TypeError: blogs.map is not a function


20. getting an error


Failed to compile

./src/component/BlogList.js

SyntaxError: C:\Project\Project\Training\React\NetNinja\dojo-blog\src\component\BlogList.js: Identifier 'blogs' has already been declared. (1:18)


This is cause, i used 'blogs' instead of 'props' in BlogList(props)


const BlogList = (blogs) => {

    const blogs = this.props.blogs;

    return (

        <div className='blog-list'>

            {blogs.map(((blog) => (

                <div className='blog-preview' key={blog.id}>

                    <h2>{blog.title}</h2>

                    <p>Written by {blog.author}</p>

                </div>

            )))}

        </div>

    );

}


--------------------------------------

corrected code is

----------------------


const BlogList = (props) => {

    const blogs = this.props.blogs;

    return (

        <div className='blog-list'>

            {blogs.map(((blog) => (

                <div className='blog-preview' key={blog.id}>

                    <h2>{blog.title}</h2>

                    <p>Written by {blog.author}</p>

                </div>

            )))}

        </div>

    );

}


export default BlogList;



--------------------


21. But still get an error

TypeError: Cannot read properties of undefined (reading 'props')

BlogList

C:/Project/....../src/component/BlogList.js:2

  1 | const BlogList = (props) => {

> 2 |     const blogs = this.props.blogs;

  3 |     return (

  4 |         <div className='blog-list'>

  5 |             {blogs.map(((blog) => (

  

22. Reason for using 'this' keyword when accessing props 

const blogs = this.props.blogs;

23. remove 'this' and you will see page in the browser

24. Let's console out props and blogs

console.log(props,blogs);


25. you can see all the properties and blogs list.


Now we can pass multiple props

---------------------------

26. eg:title , it can be dynamic value, but here we just pass a string in Home.js

27. <BlogList blogs={blogs} title="All Blogs"/>  in Home.js

28. Now we can access this from BlogList and let's use in h2 tag and out put.


-----------------------------------------------------

const BlogList = (props) => {

    const blogs = props.blogs;

    const title = props.title;

    return (

        <div className='blog-list'>

            <h2>{title}</h2>

            {blogs.map(((blog) => (

                <div className='blog-preview' key={blog.id}>

                    <h2>{blog.title}</h2>

                    <p>Written by {blog.author}</p>

                </div>

            )))}

        </div>

    );

}

--------------------------------------------------


Further we can destructure 'props'

then we don't need const variables and can use straight away.

Code will looks like

---------------------------------------------------

const BlogList = ({blogs, title}) => {

    // const blogs = props.blogs;

    // const title = props.title;

    return (

        <div className='blog-list'>

            <h2>{title}</h2>

            {blogs.map(((blog) => (

                <div className='blog-preview' key={blog.id}>

                    <h2>{blog.title}</h2>

                    <p>Written by {blog.author}</p>

                </div>

            )))}

        </div>

    );

}

----------------------------------------------------


you can play with code and check what happens after changing name of the props and variables.

Yu can see , it will  still work without any issues.

const BlogList = (props1=> {
    const blogs = props1.blogs;
    const title = props1.title;
    return (
        <div className='blog-list'>
            <h2>{title}</h2>
            {blogs.map(((blog=> (
                <div className='blog-preview' key={blog.id}>
                    <h2>{blog.title}</h2>
                    <p>Written by {blog.author}</p>
                </div>
            )))}
        </div>
    );
}

Ninja - React Basic 9 - Output Lists

1. create const to hold array of items using useState


steps

1. const [blogs, setBlogs] = useState();

2. Then add array inaside useState();

3. how to create array [{item1},{item2},{item3}]


const [blogs, setBlogs] = useState([

        { title: 'My new website', body: 'lorem ipsum...', author: 'mario', id: 1 },

        { title: 'Welcome party!', body: 'lorem ipsum...', author: 'yoshi', id: 2 },

        { title: 'Web dev top tips', body: 'lorem ipsum...', author: 'mario', id: 3 }

    ]);

Now we have list, array of items

Next how we going to show them in the template

Let's use the same return tag with Home div tag


 return (

        <div className="home">      

        </div>

    );

Inside here using mustache {} , let's try to print


1. use blogs property -> {blogs}

2. then use map method on this --> {blogs.map()}

3. map method will call , call back function for each item , where by each item around we need to return a jsx template. That's gone a go inside parathesis.

4. {blogs.map((() => ()))}

if we format

{blogs.map((() => (

               

           )))}

   

5. for each iteration , we get the access to each item. Let's call it 'blog'

6. So we give it as a input parameter

7. 

{blogs.map(((blog) => (


           )))}


8. On this item, 'blog' as we iterate we get the access to its properties. eg: title, body ...

9. what we plan to put for each item will be next

10. div with classname =  blog-preview . for each item in home page.


 return (

        <div className="home">

            {blogs.map(((blog) => (

                <div className='blog-preview'></div>

            )))}

        </div>

    );

11. When we iterate through items, each root element must have 'key' property. Reat use this to keep track in dom

12. So if we remove or add, data change -  react can keep track of those items


<div className='blog-preview' key={}></div>


13. This must be unique

14. our id will be blog.id


<div className='blog-preview' key={blog.id}></div>


15. Inside this, inside div tag you can do what you need per each item

16. let's output tile in h2 tag and , below that aouthor in para tag


<div className='blog-preview' key={blog.id}>

                    <h2>{blog.title}</h2>

                    <p>Written by {blog.author}</p>

                </div>

Now you should see the output as

---------------------------------


My new website

Written by mario


Welcome party!

Written by yoshi


Web dev top tips

Written by mario


17. For make it pretty, you can add css for preview part inside index.css


Ninja - React Basic 8 - Using State


Here we look at data or variable state change over event or  some action.
Let's create a simple variable and see what's happening in react template.

1. let's declare a variable 'name' 
2. create <p> tag and output name  --> {name}


let name = 'mario';

<p>{name}</p>

Scenario 2: Click button, change the name
1. we have function for handleClick and set name='Alex'

let's see whether name change in the template <p>{name}</p>

Note : Name value does not change in the template. It's  still 'mario'

But if you use console.log , you can see the name is changed to 'Alex'

So why not in the template ?

Reason :  The variable we created is not Reactive.
React does not watch the changes of the variable.
When value changes, template does not "ReRender"

To do this, we use a 'Hook' --> UseState
you can identify a hook with name "Use"

In order to use, we need to import
use curly braces to Destructure use state hook from React library

So let's remove what we have written inside handleClick and rewrite using useState

import {useState } from 'react';

but as we have other imports it will looks like this

import React, { Component, useState } from 'react';

Then look at step by step use of state

1. comment out variable  
// let name = 'mario';
2. Instead we gone use a Reactive value using 'useState'
3. How we do. useState is a function , so  --> useState()
4. Then we use useState with a initial value --> useState('mario')
5. Then we need to store it. Else it will be just an invoke.
6. how to do that ? we use 'const' but there is a return from the useState function. SO we use array [] to destructuring to grab two values return by hook
7. const []  = useState('mario')
8. Two return values, so first value will be name 'mario' we set. we can give an any name for it, as here it's a name of a person we can call 'name'. second value will be function, 'which we can use to chnage the value'. Normally in convention, prefix 'set' and 'name of the variable'. Here 'setName'
9. Now we can use the state to get the value for the Template, or render value for template using state
10. So at beginning 'mario' and once click , change the value for 'Alex'
11. So we need to call the function to change the value of useSet, setName
12. We call 'setName' inside our function 'handleClick'. When we call, we can pass the new value

const [name, setName] = useState('mario');

const handleClick = () => {
   setName('Alex');
}

13. This value is reactive. If the value of 'name' changes it will be change inside the template also.
14. So when we call the function, react will  Rerender the template. When it ReRender, template will have new value as it's been updated.
15. 

Note Error:
---------------
Compiled with warnings.
Failed to compile.

src\component\Home.js
  Line 4:25:  React Hook "useState" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function  react-hooks/rules-of-hooks

Search for the keywords to learn more about each error.

My Import
---------

import React, { Component, useState } from 'react';

Correct one
--------
import React, { Component, useState } from 'react';


Reason here 
1. i was calling setState outside function
2. Using a class, instead of function

Final code
---------------

import { useState } from 'react';

const Home = () =>{
    const [name, setName] = useState('mario');
    const [age, setAge] = useState(25);

    const handleClick = () => {
        setName('Alex');
        setAge(30);
    }

    return (
        <div className="home">
            <h2>HomePage</h2>
            <p>{ name } is { age } years old</p>
            <button onClick={handleClick} >Click Me</button>
        </div>
    );

}


Note: Here, Home has set on variable , holding function.
Inside , we define variables, 

export default Home;


Thursday, November 25, 2021

Ninja - React Basic 4 - Click event

  1. Create Button
  2. Create function for click event - handleClick
  3. Link the button with click function


Let's add a button below <h2> Home Page <h2> , inside Home.js

code will below

<button>Click Me</button>


Now write click function


const handleClick = () => {

    console.log('Hello World Click');

}


Here 'const' variable for function

handleClick =  name of function

then assign the function


() => {

    console.log('Hello World Click');

}


Note , we don't have parameters, that's why () before =>


3. Link the function with Click button, event 'onClick'


Note: if we pass function call instead of reference, function will call and write "Hello World Click" inside console

<button onClick={handleClick()}>Click Me</button>

you can check taking console of the browser.

It will be called when page loaded. When you click, click function won't  be called also.

This is not what we need, we need to invoke 'handleClick' function when you click the button.

How to pass reference ? --> just pass the name of the function


<button onClick={handleClick}>Click Me</button>


Note: if you pass function name with (), it's calling function

To call at event - pass only name - without () -  reference of the function


final code looks like


------------------------------------------------------------------


import React, { Component } from 'react';


const handleClick = () => {

    console.log('Hello World Click');

}


class Home extends Component {

    render() {

        return (

            <div className='home'>

                <h2>Home Page</h2>

                <button onClick={handleClick}>Click Me</button>

            </div>

        );

    }

}



---------------------------------------------------------------




Create function with parameters


1. Create a new button 

2. Create new function with parameters -> handleClickWithPara

3. Link function with button click event



const handleClickWithPara = (name) => {

    console.log('Hello '+ name)

}


function will take parameter 'name' and log in console after concatenate


Tricky part is in the calling parameter. If you  can remember top,

we can call the function with giving value itself inside call


<button onClick={handleClickWithPara('mario')}>Click With Para</button>


This will print "Hello mario" inside Console and if you click the new button "Click With Para" , nothing will happen as usual, explain in above


Now how to call this.

we need to  make an anonymous function inside dynamic call , - inside mustache


1. we need  to wrap "handleClickWithPara('mario')"  inside an anonymous function

2. So let's remove above from onClick={handleClickWithPara('mario')} and let's add arrow function as basic step

3. let's add arrow function as basic step

4. () => {}

5. after adding it will look like

6. onClick={() => {}}

7. Nothing will happen in browser or console, as nothing inside

8. IN simple, "() => {}" is function fire when user click "Click With Para" button

9. To understand bit, let's add log statement. () => {console.log('Hello')}

10. onClick={() => {console.log('Hello')}}

11. This will print 'Hello' inside console , when you click new button "Click With Para"

12. This is an anonymous function, where you don't keep in const. it will fire when the click event raised, as we have linked to "onClick" event

13. Now we can add our handleClickWithPara call inside, replacing console.log statement

14. {() => {handleClickWithPara('mario')}}


<button onClick={() => {handleClickWithPara('mario')}}>Click With Para</button>


Now you can see "Hello mario" print when new button "Click With Para" clicks


15. We don't need inner curly braces, as we have only one line. So let's remove.

 <button onClick={() => handleClickWithPara('mario')}>Click With Para</button>

16. But still we need outer curly braces as its for dynamic call


To learn more

first parameter will be the event object which will  be assign automatically as a parameter.

we can check this adding 'e' for our function without parameter -> handleClick


1. we can add 'e' as parameter  and print 'e' inside console log


const handleClick = (e) => {

    console.log('Hello World Click',e);

}


2. Now you can see the full output inside console in browser

3. So when come to second scenario, the annnonymous function get access to this event 'e' object automatically

4. Then we can pass event as above mention as access fields. eg: target


This will print when click new button. 


"Hello mario <button>​Click With Para​</button>​"


your new coding wil look like


-------------------------------------------------------------


const handleClick = (e) => {

    console.log('Hello World Click',e);

}


const handleClickWithPara = (name,e) => {

    console.log('Hello '+ name, e.target)

}


class Home extends Component {

    render() {

        return (

            <div className='home'>

                <h2>Home Page</h2>

                <button onClick={handleClick}>Click Me</button>

                <button onClick={(e) => handleClickWithPara('mario',e)}>Click With Para</button>

            </div>

        );

    }

}

------------------------------------------------------------------


Wednesday, November 24, 2021

Ninja - React Basic 3 - Add Styles

If you look at root component, you can see the 'App.css' already

Any style add inside App.css will be applied to any page in the browser

if you inspect element in browser, you can see the styles inside <head>


Let's add few styles.

So we gone a add all styles to index.css and remove App.css


new index.css

-------------------


@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;600;700&display=swap');


/* base styles */

* {

  margin: 0;

  font-family: "Quicksand";

  color: #333;

}

.navbar {

  padding: 20px;

  display: flex;

  align-items: center;

  max-width: 600px;

  margin: 0 auto;

  border-bottom: 1px solid #f2f2f2;

}

.navbar h1 {

  color: #f1356d;

}

.navbar .links {

  margin-left: auto;

}

.navbar a {

  margin-left: 16px;

  text-decoration: none;

  padding: 6px;

}

.navbar a:hover {

  color: #f1356d;

}

.content {

  max-width: 600px;

  margin: 40px auto;

  padding: 20px;

}


-----------------------------


after that let's see add inline style

let's add inline style to navbar.js


class Navbar extends Component {

    render() {

        return (

            <nav className="navbar">

                <h1>Dojo blog</h1>

                <div className="links">

                    <a href="/">Home</a>

                    <a href="/create"

                        style={{

                            color: 'white',

                            backgroundColor: '#f1356d',

                            borderRadius: '8px'

                        }}

                    >New Blog</a>

                </div>

            </nav>

        );

    }

}


Here note: we have two mustache

  • first one for dynamic variable
  • second one for object

style={{color: 'white', backgroundColor: '#f1356d',borderRadius: '8px'}}

Tuesday, November 23, 2021

Ninja - React Basic 2 - Component

Component


Let's have this structure

App.js

Navbar.js

BlogDetails.js

Sidebar.js

Categories.js

Tags.js

To Create  a new component - create new js file, better to have inside folder

create "component" folder inside "src" folder

create "Navbar.js"

src/component/Navbar.js


create code

rcc tab


will generate

------------------------

import React, { Component } from 'react';


class Navbar extends Component {

    render() {

        return (

            <div>            

            </div>

        );

    }

}


export default Navbar;


let's write some code block


class Navbar extends Component {

    render() {

        return (

            <nav className="navbar">

                <h1>Dojo blog</h1>

               <div className="links">

                    <a href="/">Home</a>

                    <a href="/create">New Blog</a>

                </div> 

            </nav>

        );

    }

}


Now let's import and use, inside App.js

once you import, you can nest it inside App.js


import Navbar from './component/Navbar'


add self close Navbar tab just above content

 <Navbar />

 

 

Code looks like

-------------


import logo from './logo.svg';

import './App.css';

import Navbar from './component/Navbar'


function App() {

  return (

    <div className="App">

      <Navbar />

      <div className="content">

        <h1>App Component</h1>

      </div>

    </div>

  );

}


export default App;



-------------


Now you can see, Nav bar loaded

http://localhost:3000/


Now let's  create a new component for "Home" page

create home.js file and continue above steps


home.js

rcc tab


------------------------------------------

import React, { Component } from 'react';


class Home extends Component {

    render() {

        return (

            <div> 

            </div>

        );

    }

}


export default Home;



--------------------------------------------


just a add dive tag with className home

add a h2 tag with homepage



import React, { Component } from 'react';


class Home extends Component {

    render() {

        return (

            <div className='home'>

                <h2>Home Page</h2>

            </div>

        );

    }

}


export default Home;



Now you can import in App.js --> 

just remove h1 tag and use <Home />



import logo from './logo.svg';

import './App.css';

import Navbar from './component/Navbar';

import Home from './component/Home';


function App() {

  return (

    <div className="App">

      <Navbar />

      <div className="content">

        <Home />

      </div>

    </div>

  );

}

export default App;

-----------------


Just like that, you can create multiple components , export them and import and use







 



Ninja - React Basic 1

https://www.youtube.com/watch?v=kVeOpcw4GWY&list=PL4cUxeGkcC9gZD-Tvwfod2gaISzfRiP9d&index=2

npx create-react-app dojo-blog


node_modules   - all dependencies

puic - public files

src -  code you write mostly goes here

App.js

index.js -  kick start app


cd dojo-blog

code 

this will open new project inside VS code


we don't need reportWebVitals();

you can remove all


Loaded App.js --> which import App from './App';   in index.js

What you see in browser inside  --> function App() ...

http://localhost:3000/


npm run start

npm install --legacy-peer-deps


function App() ....

return  --> jsx statement which will be convert to javascript

eg: className will  convert to class


Keep div with App and remove all inside <div className="App"> tag

<div className="App">


<div>


Now you should see a blank page 

http://localhost:3000/


Now add below code snipet inside App div tag


<div className="content">

   <h1>App Component</h1>

</div>


you can see, "App Component" h1 tag displayed in browser

http://localhost:3000/


Note: export default App;

-------------------------

right bottom of App.js

to use, we need to export

eg: we are using this inside index.js

here we import

import App from './App';


then after we use inside render. Rendered to DOM


ReactDOM.render(

  <React.StrictMode>

    <App />

  </React.StrictMode>,

  document.getElementById('root')

);

Wednesday, November 3, 2021

Create Table Basic - react-table (step 1)

 1. create sample app table1

npx create-react-app table1

2. verify the sample app

cd table1

npm start

3. add reat-table

npm install react-table

4. we have install the dependancy, now let's create mock values

https://mockaroo.com/

and create data as needed and save and download. 

Create a new folder inside your app 'component'

new data file 'MOCK_DATA.json'

5. create 'column.js' to add column values

// define labels for wach column
export const COLUMNS = [
    {
        Header: 'Id',
        accessor: 'id'
    },
    {
        Header: 'First Name',
        accessor:'first_name'
    },
    {
        Header: 'Last Name',
        accessor:'last_name'
    },
    {
        Header: 'Date of Birth',
        accessor:'date_of_birth'
    },
    {
        Header: 'Country',
        accessor:'country'
    },
    {
        Header: 'Phone',
        accessor:'phone'
    },
]


6. create 'BasicTable.js' to  make table


import React, { ComponentuseMemo } from 'react';
import {useTablefrom 'react-table';
import MOCK_DATA from './MOCK_DATA.json';
import COLUMNS from './columns';

class BasicTable extends Component {

    const columns = useMemo(() => COLUMNS,[])
    const data = useMemo(() => MOCK_DATA,[])

    // useTable({
    //     // columns: COLUMNS,
    //     // data: MOCK_DATA
    //     // can rewrite as

    //     // columns: columns,
    //     // data: data
    //     // further we can simplify
    //     columns,
    //     data
        
    // })

    // next we create a const to store the useTable
    const tableInstance useTable({
        columns,
        data
    })

    //step6 - render table props
    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow
    } = tableInstance

    render() {
        return (
            // step 4 - define table structure
            // convert div tag to table tag with <thead> and tbody
            // then add <tr> to both thead and tbody to add a row
            // in header use <th> and in body use <td> to add values respectively

            <table>
                <thead>
                    <tr>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td></td>
                    </tr>
                </tbody>
            </table>
        );
    }
}

export default BasicTable;