Reduxを始める

まずReact.js&webpack&babelから
#################
$ npm init
$ npm install –save-dev webpack webpack-cli webpack-dev-server
$ npm install –save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader
$ npm install –save-dev react react-dom
$ npm install –save-dev @babel/plugin-proposal-class-properties

.babelrc作成

{
	"plugins": [
		"@babel/plugin-proposal-class-properties"
	]
}

webpack.config.jsの作成
srcディレクトリの作成
#################

ここから、Reduxを使い始めたい。
公式に沿ってやっていく。(https://redux.js.org/introduction/getting-started)

npm i react-redux

$ npm install --save-dev react-redux
$ npm install --save-dev redux

basic example

import { createStore } from 'redux'

function counter(state = 0, action){
	swtich(action.type){
		case 'INCREMENT':
			return state + 1
		case 'DECREMENT':
			return state - 1
		default:
			return state
	}	
}

let store = createStore(counter)

store.subscribe(() => console.log(store.getState()))

store.dispatch({ type: 'INCREMENT' })
store.dispatch({ type: 'INCREMENT' })
store.dispatch({ type: 'INCREMENT' })

createStoreで状態遷移を管理?
全体の動きがよくわからんな。。

React.jsでカレンダーを作ろう 5

webpack.config.jsでは、moduleの前に、outputファイルを書くらしい。

context:path.join(__dirname, "src"),
	entry: "./js/client.js",
	output: {
		path: __dirname + "/src/",
		filename: "client.min.js"
	},
	module: {
		rules: [
			{
				test: /\.css$/i,
	        	use: ['style-loader', 'css-loader'],
			},
			{
			test: /\.jsx?$/,
				exclude: /(node_modules|bower_components)/,
				use: [{
					loader: 'babel-loader',
					options: {
						presets: ['@babel/preset-react', '@babel/preset-env']
					}
				}]
		}]
	},

$ npm start

きたーーーーーーーーーーーーーーーーーーーー
stylingはmoduleのCalendar.cssを編集すれば良さそうですね。
OK、とりあえず、Caledarはこれで良し^^

React.jsでカレンダーを作ろう 4

>You may need an appropriate loader to handle this file type

githubのissueを見ると、wojtekmaj が、style-loaderを入れろ、って言ってますね。

https://github.com/wojtekmaj/react-calendar/issues/97

$ npm install –save-dev css-loader
$ npm install –save-dev style-loader

で、入れたので、
$ npm start

> .react-calendar {
| width: 350px;
| max-width: 100%;
@ ../node_modules/react-calendar/dist/entry.js 48:0-25
@ ./js/client.js

あ、webpack.config.jsに追加するのね。

rules: [
			{
				test: /\.css$/i,
	        	use: ['style-loader', 'css-loader'],
			},
			{
			test: /\.jsx?$/,
				exclude: /(node_modules|bower_components)/,
				use: [{
					loader: 'babel-loader',
					options: {
						presets: ['@babel/preset-react', '@babel/preset-env']
					}
				}]
		}]

で、再度npm start

+ 66 hidden modules
ℹ 「wdm」: Compiled successfully.

OK。あれ、何も表示されない。
なぜえええええええええええええええええええええ

React.jsでカレンダーを作ろう 3

Add @babel/plugin-proposal-class-properties (https://git.io/vb4SL) to the ‘plugins’
と出ているので、インストールします

[vagrant@localhost react]$ npm install –save-dev @babel/plugin-proposal-class-properties


.babelrcに以下を追加

{
	"plugins": [
		"@babel/plugin-proposal-class-properties"
	]
}

$ npm start

RROR in ../node_modules/react-calendar/dist/Calendar.css 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> .react-calendar {
| width: 350px;
| max-width: 100%;
@ ../node_modules/react-calendar/dist/entry.js 48:0-25
@ ./js/client.js
ℹ 「wdm」: Failed to compile.

何いいいいいいいいいい
諦めんぞ、俺は。

React.jsでカレンダーを作ろう 2

さて、React.js + webpack + babelの環境ができたので、カレンダーを作っていきます。

# react-calendar のインストール
$ npm install react-calendar

jsはこうかな。

import React, { Component } from "react";
import ReactDOM from "react-dom";
import Calendar from 'react-calendar';

class Layout extends Component {
	state = {
		date: new Date(),
	}

	onChange = date => this.setState({ date })

	render(){
		return (
			<div>
				<Calendar
					onChange={this.onChange}
					value={this.state.date}
				/>
			</div>
		);
	}
}

const app = document.getElementById('app');
ReactDOM.render(<Layout/>, app);

$ npm start

ERROR in ./js/client.js
Module build failed (from ../node_modules/babel-loader/lib/index.js):
SyntaxError: /home/vagrant/react/src/js/client.js: Support for the experimental syntax ‘classProperties’ isn’t currently enabled (6:8):

4 |
5 | class Layout extends React.Component {
> 6 | state = {
| ^
7 | date: new Date(),
8 | }
9 |
Add @babel/plugin-proposal-class-properties (https://git.io/vb4SL) to the ‘plugins’ section of your Babel config to enable transformation

ん? これが必要?

npmでReact.jsの環境を作る

react-calendarがnpmなので、npmで環境を作ります。

$ npm init
$ npm install –save-dev webpack webpack-cli webpack-dev-server
$ npm install –save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader

ここまでは、これまでやってきた通り

$ npm install –save-dev react react-dom
npm ERR! code ENOSELF
npm ERR! Refusing to install package with name “react” under a package

?? package.jsonのnameがreactで同じだからインストールできないとのこと
“name”: “react1” に変更して、再度実行

$ npm install –save-dev react react-dom

続いてwebpackの設定

var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var path = require('path');

module.exports = {
	context:math.josin(__dirname, "src"),
	entry: "./js/client.js",
	module: {
		rules: [{
			text: /\.jsx?$/,
				exclude: /(node_modules|bower_components)/,
				use: [{
					loader: 'babel-loader',
					options: {
						presents: ['@babel/preset-react', '@babel/preset-env']
					}
				}]
		}]
	},
	output: {
		path: __dirname + "/src/",
		filename: "client.min.js"
	},
	plugins: debug ? [] : [
		new webpack.optimize.OccurrenceOrderPlugin(),
		new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false}),
	]
};

./src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>React</title>
	<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/cosmo/bootstrap.min.css" type="text/css" rel="stylesheet"/>
</head>
<body>
	<div id="app"></div>
	<script src="client.min.js"></script>
</body>
</html>

ここまでで、Reactの環境構築完了!?

import React from "react"
import ReactDOM from "react-dom"

class Layout extends React.Component {
	render(){
		return (
			<h1>Welcome</h1>
		);
	}
}

const app = document.getElementById('app');
ReactDOM.render(<Layout/>, app);

[vagrant@localhost react]$ webpack –mode development
Hash: 12eaf7dc67869ad64caf
Version: webpack 4.41.2
Time: 1874ms
Built at: 2019-11-20 15:39:17
Asset Size Chunks Chunk Names
client.min.js 1.08 MiB main [emitted] main
Entrypoint main = client.min.js
[./js/client.js] 2.69 KiB {main} [built]
+ 11 hidden modules

何言いいいいいいいいいいいいいい

React.jsでカレンダー機能を作りたい

カレンダー機能の要件
– 大画面で表示用
– formのカレンダーはdate pickerを使用する

react-calendarというlibraryがあるので、これをまず試したい
https://github.com/wojtekmaj/react-calendar

Installation
Add React-Calendar to your project by executing npm install react-calendar or yarn add react-calendar.

# npmでインストール
の前に、

[vagrant@localhost calendar]$ npm -v
1.3.6
[vagrant@localhost calendar]$ node -v
v0.10.48

その前にnodeとnpmをアップグレードしたい
[vagrant@localhost calendar]$ ll /etc/yum.repos.d/ | grep node
-rw-r–r–. 1 root root 464 9月 19 14:20 2014 nodesource-el.repo
[vagrant@localhost calendar]$ cat /etc/yum.repos.d/nodesource-el.repo
[nodesource]
name=Node.js Packages for Enterprise Linux 6 – $basearch
baseurl=https://rpm.nodesource.com/pub/el/6/$basearch

removeして最新を入れたい
$ sudo yum -y remove nodejs
$ sudo rm /etc/yum.repos.d/nodesource-el.repo

$ sudo yum install https://rpm.nodesource.com/pub_11.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm
$ ls -1 /etc/yum.repos.d
$ sudo yum install nodejs -y

[vagrant@localhost calendar]$ node -v
v11.15.0
[vagrant@localhost calendar]$ npm -v
6.7.0

react-calendarインストール
npm install react-calendar

あれ、その前にもう一回React.jsとwebpackを学ばないといかんやん。
ぎゃーーーーーーー

React.js 8

function TodoHeader(props){
            const remaining = props.todos.filter(todo => {
                return !todo.isDone;
        });
            return (
                <h1>
                    My Todos
                    <span>({remaining.length}/{props.todos.length})</span>
                </h1>
            );
    }
<script type="text/babel">
        (() => {

        const todos = [];

        function TodoHeader(props) {
        const remaining = props.todos.filter(todo => {
          return !todo.isDone;
        });
            return (
                <h1>
                    <button onClick={props.purge}>Purge</button>
                    My Todos
                    <span>({remaining.length}/{props.todos.length})</span>
                </h1>
            );
    }

        function TodoItem(props){
            return (
                <li key={props.todo.id}>
                    <label>
                    <input type="checkbox"
                        checked={props.todo.isDone}
                        onChange={() => props.checkTodo(props.todo)}
                    />
                    <span className={props.todo.isDone ? 'done' : ''}>
                    {props.todo.title}
                    </span>
                    </label>
                    <span className="cmd" onClick={() => props.deleteTodo(props.todo)}>[x]</span>
                </li>
            );
    }

        function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        checkTodo={props.checkTodo}
                        deleteTodo={props.deleteTodo}
                    />

                );
        });
            return (
                <ul>
                    {props.todos.length ? todos: <li>nothing to do</li>}
                </ul>
            );
    }
        function TodoForm(props){
            return (
                <form onSubmit={props.addTodo}>
                        <input type="text" value={props.item} onChange={props.updateItem}/>
                        <input type="submit" value="Add"/>
                </form>
            );
    }

        function getUniqueId(){
            return new Date().getTime().toString(36) + '-' + Math.random().toString(36);
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos,
                item: ''
            };
            this.checkTodo = this.checkTodo.bind(this);
            this.deleteTodo = this.deleteTodo.bind(this);
            this.updateItem = this.updateItem.bind(this);
            this.addTodo = this.addTodo.bind(this);
            this.purge = this.purge.bind(this);
        }

         purge() {
          if (!confirm('are you sure?')) {
            return;
          }

          const todos = this.state.todos.filter(todo => {
            return !todo.isDone;
          });
          this.setState({
            todos: todos
          });
        }

        addTodo(e){
            e.preventDefault();

            if(this.state.item.trim()===''){
            return;
        }

            const item = {
                id: getUniqueId(),
                title: this.state.item,
                isDone: false
        };

        const todos = this.state.todos.slice();
        todos.push(item);
        this.setState({
            todos: todos,
            item: ''
    });
    }

        deleteTodo(todo){
            if (!confirm('are you sure?')) {
                return;
        }

            const todos = this.state.todos.slice();
            const pos = this.state.todos.indexOf(todo);

            todos.splice(pos, 1);
            this.setState({
            todos: todos
        });
    }

        checkTodo(todo){
            const todos = this.state.todos.map(todo => {
            return {id: todo.id, title: todo.title, isDone: todo.isDone};
        });

        const pos = this.state.todos.map(todo=>{
            return todo.id;
    }).indexOf(todo.id);

    todos[pos].isDone = !todos[pos].isDone;
    this.setState({
        todos: todos
});
    }


            updateItem(e){
                this.setState({
                item: e.target.value
            })
        }

            componentDidUpdate(){
                localStorage.setItem('todos', JSON.stringify(this.state.todos));
        }

        componentDidMount(){
                this.setState({
                    todos: JSON.parse(localStorage.getItem('todos')) || []
            });
        }

            render(){
             return (
                <div className="container">
                    <TodoHeader
                        todos={this.state.todos}
                        purge={this.purge}
                    />
                    <TodoList
                    todos={this.state.todos}
                    checkTodo={this.checkTodo}
                    deleteTodo={this.deleteTodo}
                     />
                    <TodoForm
                        item={this.state.item}
                        updateItem={this.updateItem}
                        addTodo={this.addTodo}
                    />
                </div>
             );
        }

    }
        ReactDOM.render(
            <App/>,
            document.getElementById('root')
        );
    })();
    </script>

React.js 7

<script type="text/babel">
        (() => {

        const todos = [
            {id: 0, title: 'Task 0', isDone: false},
            {id: 1, title: 'Task 1', isDone: false},
            {id: 2, title: 'Task 2', isDone: true}
        ];

        function TodoItem(props){
            return (
                <li key={props.todo.id}>
                    <label>
                    <input type="checkbox"
                        checked={props.todo.isDone}
                        onChange={() => props.checkTodo(props.todo)}
                    />
                    <span className={props.todo.isDone ? 'done' : ''}>
                    {props.todo.title}
                    </span>
                    </label>
                </li>
            );
    }

        function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        checkTodo={props.checkTodo}
                    />

                );
        });
            return (
                <ul>
                    {todos}
                </ul>
            );
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos
            };
            this.checkTodo = this.checkTodo.bind(this);
        }

        checkTodo(todo){
            const todos = this.state.todos.map(todo => {
            return {id: todo.id, title: todo.title, isDone: todo.isDone};
        });

        const pos = this.state.todos.map(todo=>{
            return todo.id;
    }).indexOf(todo.id);

    todos[pos].isDone = !todos[pos].isDone;
    this.setState({
        todos: todos
});
    }

            render(){
             return (
                <div>
                    <h1>My Todo</h1>
                    <TodoList
                    todos={this.state.todos}
                    checkTodo={this.checkTodo}
                     />
                </div>
             );
        }

    }
        ReactDOM.render(
            <App/>,
            document.getElementById('root')
        );
    })();
    </script>
<script type="text/babel">
        (() => {

        const todos = [
            {id: 0, title: 'Task 0', isDone: false},
            {id: 1, title: 'Task 1', isDone: false},
            {id: 2, title: 'Task 2', isDone: true}
        ];

        function TodoItem(props){
            return (
                <li key={props.todo.id}>
                    <label>
                    <input type="checkbox"
                        checked={props.todo.isDone}
                        onChange={() => props.checkTodo(props.todo)}
                    />
                    <span className={props.todo.isDone ? 'done' : ''}>
                    {props.todo.title}
                    </span>
                    </label>
                    <span className="cmd" onClick={() => props.deleteTodo(props.todo)}>[x]</span>
                </li>
            );
    }

        function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        checkTodo={props.checkTodo}
                        deleteTodo={props.deleteTodo}
                    />

                );
        });
            return (
                <ul>
                    {todos}
                </ul>
            );
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos
            };
            this.checkTodo = this.checkTodo.bind(this);
            this.deleteTodo = this.deleteTodo.bind(this);
        }

        checkTodo(todo){
            const todos = this.state.todos.map(todo => {
            return {id: todo.id, title: todo.title, isDone: todo.isDone};
        });

        const pos = this.state.todos.map(todo=>{
            return todo.id;
    }).indexOf(todo.id);

    todos[pos].isDone = !todos[pos].isDone;
    this.setState({
        todos: todos
});
    }

            render(){
             return (
                <div className="container">
                    <h1>My Todo</h1>
                    <TodoList
                    todos={this.state.todos}
                    checkTodo={this.checkTodo}
                    deleteTodo={this.deleteTodo}
                     />
                </div>
             );
        }

    }
        ReactDOM.render(
            <App/>,
            document.getElementById('root')
        );
    })();
    </script>
function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        checkTodo={props.checkTodo}
                        deleteTodo={props.deleteTodo}
                    />

                );
        });
            return (
                <ul>
                    {props.todos.length ? todos: <li>nothing to do</li>}
                </ul>
            );
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos
            };
            this.checkTodo = this.checkTodo.bind(this);
            this.deleteTodo = this.deleteTodo.bind(this);
        }

        deleteTodo(todo){
            if (!confirm('are you sure?')) {
                return;
        }

            const todos = this.state.todos.slice();
            const pos = this.state.todos.indexOf(todo);

            todos.splice(pos, 1);
            this.setState({
            todos: todos
        });
    }
function TodoItem(props){
            return (
                <li key={props.todo.id}>
                    <label>
                    <input type="checkbox"
                        checked={props.todo.isDone}
                        onChange={() => props.checkTodo(props.todo)}
                    />
                    <span className={props.todo.isDone ? 'done' : ''}>
                    {props.todo.title}
                    </span>
                    </label>
                    <span className="cmd" onClick={() => props.deleteTodo(props.todo)}>[x]</span>
                </li>
            );
    }

        function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        checkTodo={props.checkTodo}
                        deleteTodo={props.deleteTodo}
                    />

                );
        });
            return (
                <ul>
                    {props.todos.length ? todos: <li>nothing to do</li>}
                </ul>
            );
    }
        function TodoForm(props){
            return (
                <form>
                        <input type="text" value={props.item} onChange={props.updateItem}/>
                        <input type="submit" value="Add"/>
                </form>
            );
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos,
                item: ''
            };
            this.checkTodo = this.checkTodo.bind(this);
            this.deleteTodo = this.deleteTodo.bind(this);
            this.updateItem = this.updateItem.bind(this);
        }

        deleteTodo(todo){
            if (!confirm('are you sure?')) {
                return;
        }

            const todos = this.state.todos.slice();
            const pos = this.state.todos.indexOf(todo);

            todos.splice(pos, 1);
            this.setState({
            todos: todos
        });
    }

        checkTodo(todo){
            const todos = this.state.todos.map(todo => {
            return {id: todo.id, title: todo.title, isDone: todo.isDone};
        });

        const pos = this.state.todos.map(todo=>{
            return todo.id;
    }).indexOf(todo.id);

    todos[pos].isDone = !todos[pos].isDone;
    this.setState({
        todos: todos
});
    }


            updateItem(e){
                this.setState({
                item: e.target.value
            })
        }

            render(){
             return (
                <div className="container">
                    <h1>My Todo</h1>
                    <TodoList
                    todos={this.state.todos}
                    checkTodo={this.checkTodo}
                    deleteTodo={this.deleteTodo}
                     />
                    <TodoForm
                        item={this.state.item}
                        updateItem={this.updateItem}
                    />
                </div>
             );
        }

    }
<script type="text/babel">
        (() => {

        const todos = [];

        function TodoItem(props){
            return (
                <li key={props.todo.id}>
                    <label>
                    <input type="checkbox"
                        checked={props.todo.isDone}
                        onChange={() => props.checkTodo(props.todo)}
                    />
                    <span className={props.todo.isDone ? 'done' : ''}>
                    {props.todo.title}
                    </span>
                    </label>
                    <span className="cmd" onClick={() => props.deleteTodo(props.todo)}>[x]</span>
                </li>
            );
    }

        function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        checkTodo={props.checkTodo}
                        deleteTodo={props.deleteTodo}
                    />

                );
        });
            return (
                <ul>
                    {props.todos.length ? todos: <li>nothing to do</li>}
                </ul>
            );
    }
        function TodoForm(props){
            return (
                <form onSubmit={props.addTodo}>
                        <input type="text" value={props.item} onChange={props.updateItem}/>
                        <input type="submit" value="Add"/>
                </form>
            );
    }

        function getUniqueId(){
            return new Date().getTime().toString(36) + '-' + Math.random().toString(36);
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos,
                item: ''
            };
            this.checkTodo = this.checkTodo.bind(this);
            this.deleteTodo = this.deleteTodo.bind(this);
            this.updateItem = this.updateItem.bind(this);
            this.addTodo = this.addTodo.bind(this);
        }

        addTodo(e){
            e.preventDefault();

            if(this.state.item.trim()===''){
            return;
        }

            const item = {
                id: getUniqueId(),
                title: this.state.item,
                isDone: false
        };

        const todos = this.state.todos.slice();
        todos.push(item);
        this.setState({
            todos: todos,
            item: ''
    });
    }

        deleteTodo(todo){
            if (!confirm('are you sure?')) {
                return;
        }

            const todos = this.state.todos.slice();
            const pos = this.state.todos.indexOf(todo);

            todos.splice(pos, 1);
            this.setState({
            todos: todos
        });
    }

        checkTodo(todo){
            const todos = this.state.todos.map(todo => {
            return {id: todo.id, title: todo.title, isDone: todo.isDone};
        });

        const pos = this.state.todos.map(todo=>{
            return todo.id;
    }).indexOf(todo.id);

    todos[pos].isDone = !todos[pos].isDone;
    this.setState({
        todos: todos
});
    }


            updateItem(e){
                this.setState({
                item: e.target.value
            })
        }

            render(){
             return (
                <div className="container">
                    <h1>My Todo</h1>
                    <TodoList
                    todos={this.state.todos}
                    checkTodo={this.checkTodo}
                    deleteTodo={this.deleteTodo}
                     />
                    <TodoForm
                        item={this.state.item}
                        updateItem={this.updateItem}
                        addTodo={this.addTodo}
                    />
                </div>
             );
        }

    }
        ReactDOM.render(
            <App/>,
            document.getElementById('root')
        );
    })();
    </script>

各パーツをそれぞれコンポートネントとして切り分ける。

React.js 6

<script type="text/babel">
        (() => {

        const todos = [
            {id: 0, title: 'Task 0', isDone: false},
            {id: 1, title: 'Task 1', isDone: false},
            {id: 2, title: 'Task 2', isDone: true}
        ];

        function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <li key={todo.id}>{todo.title}</li>
                );
        });
            return (
                <ul>
                    {todos}
                </ul>
            );
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos
            };
        }

            render(){
             return (
                <div>
                    <h1>My Todo</h1>
                    <TodoList todos={this.state.todos} />
                </div>
             );
        }

    }
        ReactDOM.render(
            <App/>,
            document.getElementById('root')
        );
    })();
    </script>

constで定義したstateを渡してますね。

<script type="text/babel">
        (() => {

        const todos = [
            {id: 0, title: 'Task 0', isDone: false},
            {id: 1, title: 'Task 1', isDone: false},
            {id: 2, title: 'Task 2', isDone: true}
        ];

        function TodoItem(props){
            return (
                <li key={props.todo.id}>
                    {props.todo.title}
                </li>
            );
    }

        function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                    />

                );
        });
            return (
                <ul>
                    {todos}
                </ul>
            );
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos
            };
        }

            render(){
             return (
                <div>
                    <h1>My Todo</h1>
                    <TodoList todos={this.state.todos} />
                </div>
             );
        }

    }
        ReactDOM.render(
            <App/>,
            document.getElementById('root')
        );
    })();
    </script>
function TodoItem(props){
            return (
                <li key={props.todo.id}>
                    <label>
                    <input type="checkbox"
                        checked={props.todo.isDone}
                    />
                    {props.todo.title}
                    </label>
                </li>
            );
    }