react-study-notes

I will learn about react since i am develop a image caption demo and deploy it using react. Study reference link is link. This link is learn how to develop a tic-tac-toe.

React is a declarative, efficient and flexible JavaScript library for building user interfaces. We can use short code segment (called component) to build complex UI. React has many different types component. For example, look at following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
class ShoppingList extends React.Component {
render() {
return (
<div className="shopping-list">
<h1>Shopping List for {this.props.name}</h1>
<ul>
<li>Instagram</li>
<li>WhatsApp</li>
</ul>
</div>
);
}
}

“shopping-list” is a React component class, this component receive argument called props, and show structure to screen using render method. render method uses special grammar called JSX, we can use JSX to build complex UI.

Finally, the code will be: (pls look details in link)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';

function Square(props) {
return (
<button className="square" onClick={props.onClick}>
{props.value}
</button>
);
}

class Board extends React.Component {
renderSquare(i) {
return (<Square
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)} />);
}

render() {
return (
<div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}

class Game extends React.Component {
constructor(props) {
super(props);
this.state = {
history: [{
squares : Array(9).fill(null),
}],
stepNumber: 0,
xIsNext: true,
}
}

jumpTo(step) {
this.setState({
stepNumber: step,
xIsNext: (step % 2) === 0,
})
}

render() {
const history = this.state.history;
const current = history[this.state.stepNumber];
const winner = calculateWinner(current.squares);

const moves = history.map((step, move) => {
const desc = move ?
'Go to move #' + move :
'Go to game start';
return (
<li key={move}>
<button onClick={() => this.jumpTo(move)}>{desc}</button>
</li>
)
})

let status;
if (winner) {
status = 'Winner: ' + winner;
} else {
status = 'Next Player: ' + (this.setState.xIsNext ? 'X' : 'O');
}
return (
<div className="game">
<div className="game-board">
<Board
squares={current.squares}
onClick={(i) => this.handleClick(i)}
/>
</div>
<div className="game-info">
<div>{status}</div>
<ol>{moves}</ol>
</div>
</div>
);
}

handleClick(i) {
const history = this.state.history.slice(0, this.state.stepNumber + 1);
const current = history[history.length - 1];
const squares = current.squares.slice();
if(calculateWinner(squares) || squares[i]) {
return
}
squares[i] = this.state.xIsNext ? 'X' : 'O';
this.setState({
history: history.concat([{
squares: squares,
}]),
stepNumber: history.length,
xIsNext: !this.state.xIsNext});
}
}

function calculateWinner(squares) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
for(let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if(squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}

// ========================================

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Game />);

Note that if we need get many child components’ data, or two components need communicate to each other, one father component will solve it by save child components’ data.

Image upload demo

I have develop a image upload demo using react, which frontend and backend are all developed by js.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// frontend
import './App.css';
import axios from 'axios';
import React, { useState } from 'react';

function App() {

// Define save image variables
const [image, setImage] = useState(null);

// Set image data
const getFileInfo = (e) => {
console.log('File info working!')
console.log(e.target.files[0]);
const formData = new FormData();
formData.append('image_file', e.target.files[0], e.target.files[0].name);
setImage(formData);
}

// Post image to server
const handleUpload = () => {
axios.post('http://localhost:4000/image-upload', image).then(res => {
console.log('Axios response: ', res)
})
}

// Display window
return (
<div className="App">
<h1>Image Upload</h1>
{/* Upload button */}
<button onClick={handleUpload}>Upload!</button>
{/* Choose Image to upload */}
<input type="file" onChange={getFileInfo}/>
</div>
);
}

export default App;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// backend
const express = require('express')
const app = express()
const cors = require("cors")
const multer = require('multer')
const bodyParser = require('body-parser')
const path = require('path')

// Define image process and storage
const imageUploadPath = 'D:\\code\\js\\react\\image_caption_frontend\\server\\images'
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, imageUploadPath)
},
filename: function(req, file, cb) {
cb(null, `${file.fieldname}_dateVal_${Date.now()}_${file.originalname}`)
}
})
const imageUpload = multer({
storage: storage,
// Only allow image
fileFilter: function(req, file, cb){
const filetypes = /jpeg|jpg|png/
const extname = filetypes.test(path.extname(file.originalname).toLowerCase())
const mimetype = filetypes.test(file.mimetype)
if(mimetype && extname) {
return cb(null, true)
} else {
req.fileValidationError = "File format is invalid."
return cb(null, false, req.fileValidationError)
}
}
})

// Define parser
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

// Allow access from "localhost:3000"
const corsOrigin = 'http://localhost:3000'
app.use(cors({
origin:[corsOrigin],
methods:['GET','POST'],
credentials: true
}));

// Process POST request to image-upload
app.post('/image-upload', imageUpload.array("image_file"), (req, res) => {
if(req.fileValidationError) {
res.status(200).send('File format is invalid.')
} else {
res.status(200).send('POST request received on server to /image-upload.')
}
})

// Start backend APP
const port = 4000;
app.listen(port, process.env.IP, function(){
console.log(`Server is running on port ${port}`)
});

留言

© 2024 wd-z711

⬆︎TOP