ReactExample6
๐๐ป ์๋๋ ๋ฒํผ ํด๋ฆญ์ ํ๋ก ํธ์๋(React)์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํ๊ฐ ๋ฐ๋๋ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ฝ๋ ์
๋๋ค.
Below is the code that implements the function that changes the front-end (React) and database state when a button is clicked.
๐๐ป ํ๋ก์ ํธ ์์ฑ / Create project
โ๏ธ Nodejs express server
% cd ReactExample6
% mkdir server
% cd server
% npm init -y
% npm install express
% npm install cors
% npm install pg
โ๏ธ vite+react project(Frontend)
% npm create vite@latest client --template react-ts
๐๐ป 1. PostgreSQL ํ ์ด๋ธ ์์ฑ / Create PostgreSQL table
โ๏ธ ๋จผ์ ํฐ๋ฏธ๋์์ psql์ ์ ์ํ ๋ค, ๋ฒํผ์ ์ํ๋ฅผ ์ ์ฅํ ํ
์ด๋ธ์ ๋ง๋ญ๋๋ค.
First, connect to psql in the terminal and create a table to store the button state.
โ๏ธ postgresql ์ ์ / postgresql connection
% psql postgres
โ๏ธ ํ ์ด๋ธ ์์ฑ / Create Table
CREATE TABLE button_status (
id SERIAL PRIMARY KEY,
is_active BOOLEAN NOT NULL DEFAULT false
);
-- ์ด๊ธฐ ๋ฐ์ดํฐ ์ฝ์
/ Initial data insertion
INSERT INTO button_status (is_active) VALUES (false);
๐๐ป2. Express ์๋ฒ ์ค์ (server.js) / Express server setup (server.js)
โ๏ธ server ๋๋ ํ ๋ฆฌ ๋ด์ server.jsํ์ผ์ ๋ง๋ค๊ณ ์๋์ ์ฝ๋๋ฅผ ์
๋ ฅํฉ๋๋ค.
Create a server.js file in the server directory and enter the code below.
โ๏ธpg ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํต์ ํฉ๋๋ค.
Communicate with the database using the pg library.
โ๏ธ MacOS์์ postgresql ์ค์ ์ ํ์ง ์์ ๊ฒฝ์ฐ user๋ ์์ ์ MacOS๊ณ์ ์ด๋ฉฐ ํจ์ค์๋๋ ๊ณต๋ฐฑ์
๋๋ค.
If you have not configured postgresql on MacOS, user is your MacOS account and password is blank.
const express = require('express');
const { Pool } = require('pg');
const cors = require('cors');
const app = express();
app.use(cors());
app.use(express.json());
const pool = new Pool({
user: 'yourid', // ๋ณธ์ธ์ ๊ณ์ ๋ช
/ Your account name
host: 'localhost',
database: 'postgres', // ๋ณธ์ธ์ DB๋ช
/ Your DB name
password: '', // ๋ณธ์ธ์ ๋น๋ฐ๋ฒํธ / your password
port: 5432,
});
// ํ์ฌ ์ํ ๊ฐ์ ธ์ค๊ธฐ / Get current status
app.get('/status', async (req, res) => {
try {
const result = await pool.query('SELECT is_active FROM button_status WHERE id = 1');
res.json(result.rows[0]);
} catch (err) {
res.status(500).send(err.message);
}
});
// ์ํ ์
๋ฐ์ดํธํ๊ธฐ / Update your status
app.post('/toggle', async (req, res) => {
const { isActive } = req.body;
try {
const result = await pool.query(
'UPDATE button_status SET is_active = $1 WHERE id = 1 RETURNING *',
[isActive]
);
res.json(result.rows[0]);
} catch (err) {
res.status(500).send(err.message);
}
});
app.listen(3000, () => console.log('Server running on http://localhost:3000'));
โ๏ธ ์๋ฒ๊ฐ ์คํ๋๋์ง ํ์ธ ํ๊ธฐ / Check if the server is running
โญ๏ธ ์๋ฒ๊ฐ ๋ฐ๋ก ์คํ ์ข
๋ฃ๋๋ฉด ํฌํธ๋ฒํธ๋ฅผ ๋ฐ๊พธ์ธ์ ์ ๋ 5000๋ฒ์ฐ๋ฉด ์๋ฒ๊ฐ ์คํ์ข
๋ฃ๋๋ค์.
If the server stops running immediately, change the port number. When I use 5000, the server stops running.
% node server.js
Server running on http://localhost:3000
๐๐ป 3. Vite + React ํ๋ก ํธ์๋ (App.jsx) / Vite + React frontend (App.jsx)
โ๏ธ axios๋ชจ๋์ ์ค์นํฉ๋๋ค.( client/ )
Install the axios module ( client/ )
% npm install axios
โ๏ธ axios๋ฅผ ์ฌ์ฉํด ์๋ฒ์ ํต์ ํ๋ฉฐ ๋ฒํผ์ UI๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค.
Communicate with the server using axios and change the UI of the button.
import { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [isActive, setIsActive] = useState(false);
// ์ฒ์ ๋ก๋๋ ๋ ์๋ฒ์์ ์ํ ๊ฐ์ ธ์ค๊ธฐ
// Get state from server when first loaded
useEffect(() => {
axios.get('http://localhost:3000/status')
.then(res => setIsActive(res.data.is_active))
.catch(err => console.error(err));
}, []);
// ๋ฒํผ ํด๋ฆญ ์ ํ ๊ธ ์์ฒญ / Request toggle when button is clicked
// Request toggle when button is clicked
const handleToggle = async () => {
try {
const nextState = !isActive;
const res = await axios.post('http://localhost:3000/toggle', { isActive: nextState });
setIsActive(res.data.is_active);
} catch (err) {
alert("์๋ฒ ์ฐ๊ฒฐ์ ์คํจํ์ต๋๋ค./Failed to connect to server.");
}
};
return (
<div
style={{
display: "flex",
flexDirection: "column",
justifyContent: "center", // ์ธ๋ก ์ค์ ์ ๋ ฌ / Vertical center alignment
alignItems: "center", // ๊ฐ๋ก ์ค์ ์ ๋ ฌ / horizontal center alignment
height: "100vh", // ํ๋ฉด ์ ์ฒด ๋์ด ์ฌ์ฉ / Use full screen height
width: "100vw", // ํ๋ฉด ์ ์ฒด ๋๋น ์ฌ์ฉ / Use full screen width
margin: 0, // ๊ธฐ๋ณธ ์ฌ๋ฐฑ ์ ๊ฑฐ / Remove default margins
}}
>
<div style={{ textAlign: "center", marginTop: "50px" }}>
<h2>
ํ์ฌ ์ํ/Current Status:{" "}
{isActive ? "๐ต ํ์ฑ/Active" : "๐ด ๋นํ์ฑ/inActive"}
</h2>
<button
onClick={handleToggle}
style={{
padding: "10px 20px",
fontSize: "16px",
backgroundColor: isActive ? "#4CAF50" : "#f44336",
color: "white",
border: "none",
borderRadius: "5px",
cursor: "pointer",
}}
>
{isActive ? "๋นํ์ฑํํ๊ธฐ/InActivate" : "ํ์ฑํํ๊ธฐ/Activate"}
</button>
</div>
</div>
);
}
export default App;
๐๐ป ์คํฌ๋ฆฐ ์ท / ScreenShot
โ๏ธ InActive

โ๏ธ Active

โ๏ธ postgresql
