Sunday 27 May 2018

react route reactstrap table form CRUD

project link: http://chuanshuoge1.github.io/reactstrap






Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { BrowserRouter} from 'react-router-dom'

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>, document.getElementById('root'));
registerServiceWorker();

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

App.js

import React, { Component } from 'react';
import './App.css';
import { Switch, Route, Link } from 'react-router-dom';
import  Header  from './Header';
import { Home } from './Home';
import { Schedule } from './Schedule';
import { Roster } from './Roster';

class App extends Component {
    render() {
        return (
            <div>
                <Header />
                <Main />
            </div>
        );
    }
}


const Main = () => (
    <main>
        <Switch>
            <Route exact path='/' component={Home} />
            <Route path='/roster' component={Roster} />
            <Route path='/schedule' component={Schedule} />
        </Switch>
    </main>
)

export default App;

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

App.css

.my-link-color {
    color: white;
}

    .my-link-color:hover {
        color: gainsboro;
        text-decoration: none;
    }

    .my-link-color:focus {
        color: gold;
        text-decoration: none;
    }

.my-tab-color {
    background-color: antiquewhite;
    color: white;
}

.my-tab-content-color {
    background-color: antiquewhite;
}

.my-schedule-form {
    background-color: palegreen;
}

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

Header.js

import React, { Component } from 'react';
import { Switch, Route, Link } from 'react-router-dom'
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';

import {
    Collapse,
    Navbar,
    NavbarToggler,
    NavbarBrand,
    Nav,
    NavItem,
    NavLink,
} from 'reactstrap';

export default class Example extends React.Component {
    constructor(props) {
        super(props);

        this.toggle = this.toggle.bind(this);
        this.state = {
            isOpen: false
        };
    }
    toggle() {
        this.setState({
            isOpen: !this.state.isOpen
        });
    }
    render() {
        return (
            <div>
                <Navbar className="navbar-inverse bg-secondary" dark expand="sm">
                    <NavbarBrand><Link to='/' className="my-link-color">Reactstrap</Link></NavbarBrand>
                    <NavbarToggler onClick={this.toggle} />
                    <Collapse isOpen={this.state.isOpen} navbar>
                        <Nav className="sm-auto" navbar>
                            <NavItem>
                                <NavLink><Link to='/' className="my-link-color">Home</Link></NavLink>
                            </NavItem>
                            <NavItem>
                                <NavLink><Link to='/schedule' className="my-link-color">Schedule</Link></NavLink>
                            </NavItem>
                            <NavItem>
                                <NavLink><Link to='/roster' className="my-link-color">Roster</Link></NavLink>
                            </NavItem>
                        </Nav>
                    </Collapse>
                </Navbar>
            </div>
        );
    }
}

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

Home.js

import React, { Component } from 'react';

export const Home = () => (
    <div>
        <h1>Welcome to the Tornadoes Website!</h1>
    </div>
)

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

Schedule.js

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

Roster.js

import React, { Component } from 'react';
import { Switch, Route, Link } from 'react-router-dom';
import { Player, PlayerAPI } from './Players';

export const Roster = () => (
    <Switch>
        <Route exact path='/roster' component={FullRoster} />
        <Route path='/roster/:number' component={Player} />
    </Switch>
)

const FullRoster = () => (
    <div>
        <ul>
            {
                PlayerAPI.all().map(p => (
                    <li key={p.number}>
                        <Link to={`/roster/${p.number}`}>{p.name}</Link>
                    </li>
                ))
            }
        </ul>
    </div>
)

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

Player.js

import React, { Component } from 'react';
import { Switch, Route, Link } from 'react-router-dom'

export const Player = (props) => {
    const player = PlayerAPI.get(
        parseInt(props.match.params.number, 10)
    )
    if (!player) {
        return <div>Sorry, but the player was not found</div>
    }
    return (
        <div>
            <h1>{player.name} (#{player.number})</h1>
            <h2>Position: {player.position}</h2>
            <Link to='/roster'>Back</Link>
        </div>
    )
}



export const PlayerAPI = {
    players: [
        { number: 1, name: "Ben Blocker", position: "G" },
        { number: 2, name: "Dave Defender", position: "D" },
        { number: 3, name: "Sam Sweeper", position: "D" },
        { number: 4, name: "Matt Midfielder", position: "M" },
        { number: 5, name: "William Winger", position: "M" },
        { number: 6, name: "Fillipe Forward", position: "F" }
    ],
    all: function () { return this.players },
    get: function (id) {
        const isPlayer = p => p.number === id
        return this.players.find(isPlayer)
    }
}


Monday 21 May 2018

Acadmind


https://www.youtube.com/channel/UCSJbGtTlrDami-tDGPUV9-w/featured

react route

install
npm install --save react-router-dom

app.js

import React, { Component } from 'react';
import './App.css';
import { Switch, Route, Link } from 'react-router-dom'

class App extends Component {
    render() {
        return (
            <div>
                <Header />
                <Main />
            </div>
        );
    }
}

const Header = () => (
    <header>
        <nav>
            <ul>
                <li><Link to='/'>Home</Link></li>
                <li><Link to='/roster'>Roster</Link></li>
                <li><Link to='/schedule'>Schedule</Link></li>
            </ul>
        </nav>
    </header>
)

const Main = () => (
    <main>
        <Switch>
            <Route exact path='/' component={Home} />
            <Route path='/roster' component={Roster} />
            <Route path='/schedule' component={Schedule} />
        </Switch>
    </main>
)

const Home = () => (
    <div>
        <h1>Welcome to the Tornadoes Website!</h1>
    </div>
)

const Schedule = () => (
    <div>
        <ul>
            <li>6/5 @ Evergreens</li>
            <li>6/8 vs Kickers</li>
            <li>6/14 @ United</li>
        </ul>
    </div>
)

const Roster = () => (
    <Switch>
        <Route exact path='/roster' component={FullRoster} />
        <Route path='/roster/:number' component={Player} />
    </Switch>
)

const Player = (props) => {
    const player = PlayerAPI.get(
        parseInt(props.match.params.number, 10)
    )
    if (!player) {
        return <div>Sorry, but the player was not found</div>
    }
    return (
        <div>
            <h1>{player.name} (#{player.number})</h1>
            <h2>Position: {player.position}</h2>
            <Link to='/roster'>Back</Link>
        </div>
    )
}

const FullRoster = () => (
    <div>
        <ul>
            {
                PlayerAPI.all().map(p => (
                    <li key={p.number}>
                        <Link to={`/roster/${p.number}`}>{p.name}</Link>
                    </li>
                ))
            }
        </ul>
    </div>
)

const PlayerAPI = {
    players: [
        { number: 1, name: "Ben Blocker", position: "G" },
        { number: 2, name: "Dave Defender", position: "D" },
        { number: 3, name: "Sam Sweeper", position: "D" },
        { number: 4, name: "Matt Midfielder", position: "M" },
        { number: 5, name: "William Winger", position: "M" },
        { number: 6, name: "Fillipe Forward", position: "F" }
    ],
    all: function () { return this.players },
    get: function (id) {
        const isPlayer = p => p.number === id
        return this.players.find(isPlayer)
    }
}

export default App;

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

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { BrowserRouter} from 'react-router-dom'

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>, document.getElementById('root'));
registerServiceWorker();


reference:
https://www.youtube.com/watch?v=eofpZPRUnP8
https://www.youtube.com/watch?v=5pt_igBTCsI

react-bootstrap
https://stackoverflow.com/questions/40037657/how-to-include-bootstrap-css-and-js-in-reactjs-app

react-router
https://medium.com/@pshrmn/a-simple-react-router-v4-tutorial-7f23ff27adf

Sunday 20 May 2018

react-redux


page loaded from github

click load tweets, add, update tweet

observe state change in log


input box update user

project src folder

reducer folder

action folder

----------------------------------------------------------------------------------
//src folder
//index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

import App1 from "./appStart";
import registerServiceWorker from './registerServiceWorker';
import { Provider } from "react-redux";
import store from "./store";

ReactDOM.render(
    <Provider store={store}>
        <App1 />
    </Provider>, document.getElementById('root'));

registerServiceWorker();

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

//appstart.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchUser, setUserName, setUserAge } from './actions/userActions';
import { fetchTweets, addTweet, updateTweet } from './actions/tweetsActions';

class App1 extends Component {

    componentWillMount() {
        this.props.dispatch(fetchUser());
    }

    handle_loadTweet() {
        this.props.dispatch(fetchTweets());
    }

    handle_addTweet(id) {
        this.props.dispatch(addTweet(id,"new title"));
    }

    handle_updateTweet(id) {
        this.props.dispatch(updateTweet(id, "updated title"));
    }

    handle_updateUserName(e) {
        if (e.keyCode === 13) {
            this.props.dispatch(setUserName(e.target.value));
        }
    }

    handle_setUserAge(e) {
        if (e.keyCode === 13) {
            this.props.dispatch(setUserAge(parseInt( e.target.value)));
        }
    }

    render() {

        console.log(this.props.user);
        console.log("user fetched", this.props.userFetched);
        console.log("tweet fetched", this.props.tweetFetched);
        console.log("tweets[]", this.props.tweets);

        const { user, tweets } = this.props;        

        const load_tweet_button = tweets.length ? <span /> :
            <button onClick={() => this.handle_loadTweet()}>load tweets</button>;

        const mappedTweets = tweets.map((tweet, index) =>
            <li key={index}>{tweet.title}</li>
        ).slice(tweets.length-10, tweets.length);

        return (
            <div>
                redux
                <p>{user.name} {this.props.user.age}</p>
                <input type="text" onKeyDown={(e) => this.handle_updateUserName(e)} defaultValue="update name press enter" />
                <input type="number" onKeyDown={(e) => this.handle_setUserAge(e)} defaultValue={20} />
                <br />
                {load_tweet_button}
                <button onClick={() => this.handle_addTweet(tweets.length + 1)}>add tweet</button>
                <button onClick={() => this.handle_updateTweet(tweets.length)}>update last tweet</button>
                <ul>{mappedTweets}</ul>
            </div>
        );
    }
}

export default connect(
    (store) => {
        return {
            user: store.user.user,
            userFetched: store.user.fetched,
            tweetFetched: store.tweets.fetched,
            tweets: store.tweets.tweets,
        };
    }
)(App1);

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

//store.js

import { applyMiddleware, createStore } from 'redux';
import logger from 'redux-logger';
import thunk from 'redux-thunk';
import promiseMiddleware from 'redux-promise-middleware';

import reducer from "./reducers";

const middleware = applyMiddleware(promiseMiddleware(), thunk, logger);

export default createStore(reducer, middleware);

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

//action folder
//tweetAction.js

import axios from 'axios';

export function fetchTweets() {
    return {
        type: "fetch_tweet",
        payload: axios.get("https://jsonplaceholder.typicode.com/posts")
    }
}

export function addTweet(id, text) {
    return {
        type: "add_tweet",
        payload:{
            id,
            text,
        },
    }
}

export function updateTweet(id, text) {
    return {
        type: "update_tweet",
        payload: {
            id,
            text,
        },
    }
}

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

//userActions.js

export function fetchUser() {
    return {
        type: "fetch_user_FULFILLED",
        payload: {
            name: "will",
            age:35,
        }
    }
}

export function setUserName(name) {
    return {
        type: "set_user_name",
        payload:name,
    }
}

export function setUserAge(age) {
    return {
        type: "set_user_age",
        payload:age,
    }
}

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

//reducer folder
//index.js

import { combineReducers } from 'redux';

import tweets from "./tweetsReducer";
import user from "./userReducer";

export default combineReducers(
    {
        tweets,
        user,
    })

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

//tweetReducer

export default function reducer(
    state = {
        tweets: [],
        fetching: false,
        fetched: false,
        error: null,
    },
    action
) {
    switch (action.type) {
        case "fetch_tweet_PENDING": {
            return { ...state, fetching: true }
            break;
        }
        case "fetch_tweet_FULFILLED": {
            return {
                ...state,
                fetching: false,
                fetched: true,
                tweets: action.payload.data,
            }
            break;
        }
        case "fetch_tweet_REJECTED": {
            return {
                ...state,
                fetching: false,
                error: action.payload,
            }
            break;
        }

        case "add_tweet": {
            const newTweets = [...state.tweets];
            const added_tweet = { "id": action.payload.id, "title": action.payload.text };
            newTweets.push(added_tweet);

            return {
                ...state,
                tweets: newTweets,
            }
        }

        case "update_tweet": {
            const { id, text } = action.payload;
            const newTweets = [...state.tweets];
            const tweetToUpdate = newTweets.findIndex(tweet => tweet.id === id);
            newTweets[tweetToUpdate].title = text;

            return {
                ...state,
                tweets: newTweets,
            }
        }

        case "delete_tweet": {
            return {
                ...state,
                tweets: state.tweets.filter(tweet => tweet.id !== action.payload),
            }
        }
    }
    return state;
}

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

//userReducer

export default function reducer(
    state = {
        user: {
            id: null,
            name: null,
            age:null,
        },
        fetching: false,
        fetched: false,
        error: null,
    },
    action
) {
    switch (action.type) {
        case "fetch_user_PENDING": {
            return { ...state, fetching: true }
            break;
        }
        case "fetch_user_FULFILLED": {
            return {
                ...state,
                fetching: false,
                fetched: true,
                user: action.payload,
            }
            break;
        }
        case "fetch_user_REJECTED": {
            return {
                ...state,
                fetching: false,
                error: action.payload,
            }
            break;
        }
        case "set_user_name": {

            return {
                ...state,
                user: { ...state.user, name: action.payload },
            }
        }

        case "set_user_age": {

            return {
                ...state,
                user: { ...state.user, age: action.payload },
            }
        }
    }
    return state;
}

react host on github

Prerequisites

  1. An adequate version of Node.js is installed. Here's the adequate version I use:
    $ node --version
    v6.10.1
  2. An adequate version of npm is installed. Here's the adequate version I use:
    $ npm --version
    3.10.10
  3. An adequate version of create-react-app is installed. Here's the adequate version I use:
    $ create-react-app --version
    1.3.1
    In the case of create-react-app, you can either install it globally (i.e. $ npm install -g create-react-app) or install it locally (i.e. $ npm install create-react-app). If you choose the latter, you will have to specify its path whenever you invoke it (e.g. path/to/node_modules/.bin/create-react-app).
  4. (Optional) An adequate version of sed is installed. Here's the adequate version I use:
    $ sed --version
    sed (GNU sed) 4.4
  5. GitHub account. :octocat:

Procedure

  1. Create an empty repository on GitHub. (2 minutes)
    • For this tutorial, I'll create a repository named react-gh-pages.
    • By empty, I mean without a README.md file, a .gitignore file, a LICENSE file, or any other files.
  2. Create a new React app on your computer. (5 minutes)
    $ create-react-app react-gh-pages
    • This is the app you will deploy to GitHub Pages in step 7.
    • I opted to give the app the same name as my GitHub repository (i.e. react-gh-pages). However, you can name them differently from one another (e.g. you can name your app app-123 and your GitHub Repository repo-456).
    • This will create a new folder named react-gh-pages (or whatever you named your app) on your computer.
  3. Install the gh-pages package as a "dev-dependency" of the app. (1 minute)
    $ cd react-gh-pages
    $ npm install gh-pages --save-dev
    
    • The commands shown in the following steps can all be issued from within the app's folder.
  4. Add some properties to the app's package.json file. (3 minutes)
    • At the top level, add a homepage property. Define its value to be the string http://{username}.github.io/{repo-name}, where {username} is your GitHub username, and {repo-name} is the name of the GitHub repository you created in step 1. Since my GitHub username is gitname and the name of my GitHub repository is react-gh-pages, I added the following property:
    //...
    "homepage": "http://gitname.github.io/react-gh-pages"
    • In the existing scripts property, add a predeploy property and a deploy property, each having the values shown below:
    "scripts": {
      //...
      "predeploy": "npm run build",
      "deploy": "gh-pages -d build"
    }
    • Shortcut: Instead of adding those properties using a text editor; if I have sed installed on my system, I can add the properties by issuing the following shell commands:
    $ sed -i '5i\  "homepage": "http://gitname.github.io/react-gh-pages",' ./package.json
    $ sed -i '15i\    "predeploy": "npm run build",' ./package.json
    $ sed -i '16i\    "deploy": "gh-pages -d build",' ./package.json
  5. Create a git repository in the app's folder. (1 minute)
    $ git init
    Initialized empty Git repository in C:/path/to/react-gh-pages/.git/
    
  6. Add the GitHub repository as a "remote" in your local git repository. (1 minute)
    $ git remote add origin https://github.com/gitname/react-gh-pages.git
    
    • This will make it so the gh-pages package knows where you want it to deploy your app in step 7.
    • It will also make it so git knows where you want it to push your source code (i.e. the commits on your masterbranch) in step 8.
  7. Generate a production build of your app, and deploy it to GitHub Pages. (2 minutes)
    $ npm run deploy
    
    • That's it! Your app is now accessible at the URL you specified in step 4.
    • In my case, my app is now accessible at: https://gitname.github.io/react-gh-pages/
    • I recommend exploring the GitHub repository at this point. When I explored it, I noticed that, although a masterbranch did not exist, a gh-pages branch did exist. I noticed the latter contained the built app code, as opposed to the app's source code.
  8. Optionally, commit your source code to the "master" branch and push your commit to GitHub. (1 minute)
    $ git add .
    $ git commit -m "Create a React app and publish it to GitHub Pages"
    $ git push origin master
    
    • I recommend exploring the GitHub repository once again at this point. When I did that, I noticed that a masterbranch now existed, and it contained the app's source code.
    • So, the master branch held the source code, and the gh-pages branch held the built app code.

reference:
https://github.com/gitname/react-gh-pages

react local host

//cd project folder, create final build

npm run build

//build folder is created

serve -s build


ctrl+c to terminate serving

cache or cookie may keep website going for a while.


reference:
https://stackoverflow.com/questions/45346849/how-to-stop-npm-serve

Wednesday 16 May 2018

redux


install
npm install --save redux
npm install --save react-redux
npm install --save-dev redux-devtools
npm i --save redux-logger
npm install --save redux-thunk
npm i redux-promise-middleware -s
npm i -S react-redux



reference:
https://www.youtube.com/watch?v=93p3LxR9xfM
https://www.npmjs.com/package/redux
https://medium.com/backticks-tildes/setting-up-a-redux-project-with-create-react-app-e363ab2329b8
https://github.com/pburtchaell/redux-promise-middleware/blob/master/docs/introduction.md

thunk
https://www.npmjs.com/package/redux-thunk

connect
https://blog.benestudio.co/5-ways-to-connect-redux-actions-3f56af4009c8

react fetch data code

<head>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
<div id="root4"></div>
<script type="text/babel">

const url = "https://jsonplaceholder.typicode.com/posts";

class App4 extends React.Component {

   constructor(props) {
        super(props);

        this.state={
           data:[],
           loading:false,
           error: null,
           error_message:"",
           }
     }

   handle_click() {

    this.setState({ loading: true });

    fetch(url)
      .then(response => response.json())
      .then((data) => this.setState({ data: data, loading:false }))
      .catch((error) => this.setState({ error: false, error_message:error.message }));
  }

   render(){

       const data_array = this.state.data.map(
           (item,index)=>{

                return(
                   <tr key={index}>
                      <td>{item.userId}</td>
                      <td>{item.id}</td>
                      <td>{item.title}</td>
                      <td>{item.body}</td>
                   </tr>
                );
           }
       );

       const status = this.state.loading? "loading": "";     

       return(
             <div>
                <p>{status} data from {url}</p>
                <p>{this.state.error_message}</p>
                <button onClick={()=>this.handle_click()}>fetch data</button>
                <table>
                   <tbody>
                      {data_array}
                   </tbody>
                </table>
             </div>
         );
     }

}

ReactDOM.render(
    <App4 />,
    document.getElementById('root4')
);
</script>
</body>

react fetch data



reference:
https://www.robinwieruch.de/react-fetching-data/

Tuesday 15 May 2018

react prevState, history code

<style>
.increment_input{
    width:30px;
   text-align:center;
}

.increment_input_tip{
   display:none;
}

.increment_input:hover+.increment_input_tip{
   display:inline-flex;
   color:lightgreen;
}
</style>

<head>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>


<br />
<div id="root3">
</div>
<script type="text/babel">
class Fabonacci extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            history: [{ value: 1 }, { value: 1 }],
            current_step: 1,
        };
    }

    handleClick_retrieveStep(step_num) {

        const h = this.state.history.slice(0, step_num);

        this.setState(
            {
                history: h,
                current_step: step_num,
            }
        );
    }

    handleClick_showStepvalue(step_num){

        this.setState({current_step:step_num});
    }

    handleClick_nextStep() {

        const history_length = this.state.history.length;
        const h = this.state.history.slice(0, history_length);

        const current_value = h[history_length - 1].value;
        const previous_value = (history_length === 1) ? 0 : h[history_length - 2].value;
        const future_value = current_value + previous_value;

        this.setState(
            {
                history: h.concat({ value: future_value }),
                current_step: history_length + 1,
            }
        );
    }

    handleClick_imcrement() {
        this.setState(
            (prevState, props) => {
                const value1 = prevState.history[0].value + props.increment;
                const value2 = prevState.history[1].value + props.increment;

                const h = prevState.history.slice(0, 2);
                h[0].value = value1;
                h[1].value = value2;

                return (
                    {
                        history: h,
                        current_step: 1,
                    }
                );
            }
        );
    }

    render() {

        const current_step = this.state.current_step;
        const current_stepValue = this.state.history[current_step - 1].value;

        const button_array = this.state.history.map(
            (item, index) => {
                const button_step = index + 1;
                const button_description = "retrieve step " + button_step;
                const button_description2 = "show step " +button_step+" value";

                return (
<li key={button_step}>
                        <button onClick={() => this.handleClick_retrieveStep(button_step)}>
                            {button_description}</button>
                        <span>  </span>
                        <button onClick={() => this.handleClick_showStepvalue(button_step)}>
                            {button_description2}</button>
                    </li>
);
            }
        );

        const all_history_values = this.state.history.map(
            (item, index) => {
                return (
                    <span key={index}>{item.value} </span>
                );
            }
        );

        return (

            <div>
                <p>
all history values: ( {all_history_values} )</p>
<p>
value at step {current_step} is {current_stepValue} </p>
<button onClick={() => this.handleClick_imcrement()}>increase x1,x2 by {this.props.increment}</button>
                <span>  </span>
                <button onClick={() => this.handleClick_nextStep()}>increase 1 step >></button>
                <ol>{button_array}</ol>
</div>
);
    }
}

class App3 extends React.Component {

     constructor(props) {
        super(props);

        this.state={increment:1}
     }
   
     handleKeydown(e){
       if(e.keyCode===13){
            this.setState({increment: parseInt(e.target.value)});
         }
     }

    render() {

        return (
            <div>
                <p>
formular x(n-1) + x(n) = x(n+1) where x1, x2 initial value = 1</p>
                <span>increase x1, x2 by </span>
                <input className="increment_input" type="number" defaultValue={1} onKeyDown={(e)=>this.handleKeydown(e)}></input>
                <span className="increment_input_tip">press enter to save, check change on increase x1,x2 button</span>
<Fabonacci increment={this.state.increment} />
            </div>
);
    }
}

ReactDOM.render(
    <App3 />,
    document.getElementById('root3')
);
</script>