Python Flask
https://flask.palletsprojects.com/en/2.2.x/installation/
Create an environment
C:\flask_dev>py -3 -m venv venv
Activate the environment
C:\flask_dev>venv\Scripts\activate
Install Flask
venv C:\flask_dev>pip install Flask
C:\flask_dev\flaskreact\app.py
Install requirements
Flask-SQLAlchemy
Flask-SQLAlchemy is an extension for Flask that adds support for SQLAlchemy to your application.
https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/
(venv) PS C:\flask_dev\flaskreact>pip install -U Flask-SQLAlchemy
Flask-Cors
A Flask extension for handling Cross Origin Resource Sharing (CORS), making cross-origin AJAX possible.
https://pypi.org/project/Flask-Cors/
(venv) PS C:\flask_dev\flaskreact>pip install -U flask-cors
C:\flask_dev\flaskreact\app.py
#C:\flask_dev\flaskreact\app.py from flask import Flask, request, jsonify from flask_cors import CORS, cross_origin #ModuleNotFoundError: No module named 'flask_cors' = pip install Flask-Cors from models import db, User app = Flask(__name__) app.config['SECRET_KEY'] = 'cairocoders-ednalan' #app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///flaskdb.db' # Databse configuration mysql Username:password@hostname/databasename app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:''@localhost/flaskreact' SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_ECHO = True CORS(app, supports_credentials=True) db.init_app(app) with app.app_context(): db.create_all() @app.route("/") def hello_world(): return "Hello, World!" @app.route('/users/<int:page>/<int:per_page>', methods=['GET']) #http://127.0.0.1:5000/users/1/4 def posts(page=1, per_page=10): total = User.query.count() print(total) posts = User.query.order_by(User.id.asc()) posts = posts.paginate(page=page, per_page=per_page) return jsonify({ 'total': total, 'page': page, 'per_page': per_page, 'data': [{ 'id': p.id, 'fullname': p.name, 'email': p.email, 'password': p.password, 'photo': p.photo } for p in posts.items] }) if __name__ == "__main__": app.run(debug=True)C:\flask_dev\flaskreact\models.py
#C:\flask_dev\flaskreact\models.py from flask_sqlalchemy import SQLAlchemy from uuid import uuid4 db = SQLAlchemy() def get_uuid(): return uuid4().hex class User(db.Model): __tablename__ = "users" id = db.Column(db.String(11), primary_key=True, unique=True, default=get_uuid) name = db.Column(db.String(150), unique=True) email = db.Column(db.String(150), unique=True) password = db.Column(db.Text, nullable=False) photo = db.Column(db.String(150), unique=True)run (venv) C:\flask_dev\flaskreact>flask run
http://127.0.0.1:5000/users/1/4
users.sql : https://github.com/cairocodes/cairocoders/blob/main/users.sql
React JS
https://create-react-app.dev/
Create Project
C:\react-js>npx create-react-app myreactdev
Run
C:\react-js\myreactdev> npm start
C:\react-js\myreactdev\src\App.js
//C:\react-js\myreactdev\src\App.js import React, { useEffect, useState } from "react"; import "./App.css"; import InfiniteScroll from "react-infinite-scroll-component"; //npm install --save react-infinite-scroll-component = https://github.com/ankeetmaini/react-infinite-scroll-component import Users from "./components/Users"; import Loader from "./components/Loader"; import End from "./components/End"; function App() { const [items, setItems] = useState([]); const [hasMore, sethasMore] = useState(true); const [page, setpage] = useState(2); const perPage = 8; useEffect(() => { const getUsers = async () => { const res = await fetch( `http://127.0.0.1:5000/users/1/${perPage}` ); const usersdata = await res.json(); setItems(usersdata.data); console.log(usersdata.data); }; getUsers(); }, []); const fetchUsers = async () => { const res = await fetch( `http://127.0.0.1:5000/users/${page}/${perPage}` ); const scrolldata = await res.json(); return scrolldata.data; }; const fetchData = async () => { const usersServer = await fetchUsers(); setItems([...items, ...usersServer]); if (usersServer.length === 0 || usersServer.length < 20) { sethasMore(false); } setpage(page + 1); }; return ( <InfiniteScroll dataLength={items.length} //render next data next={fetchData} hasMore={hasMore} loader={<Loader />} endMessage={<End />} > <div className="container"> <div className="row justify-content-center"> <div className="col-12 col-sm-8 col-lg-6"> <div className="section_heading text-center wow fadeInUp"> <h3>ReactJS Python Flask Infinite Scroll Pagination | SQLAlchemy Mysql</h3> <div className="line"></div> </div> </div> </div> <div className="row" style={{padding: 20}}> {items.map((item) => { return <Users key={item.id} item={item} />; })} </div> </div> </InfiniteScroll> ); } export default App;C:\react-js\myreactdev\src\components\Users.js
//C:\react-js\myreactdev\src\components\Users.js import React, { } from "react"; function Users({item: { fullname, email, photo }}) { return ( <div className="col-12 col-sm-6 col-lg-3"> <div className="single_advisor_profile wow fadeInUp"> <div className="advisor_thumb"> <img alt="pic" src={photo} width="315" height="315"/></div> <div className="single_advisor_details_info"> <h6>{fullname}</h6> <p className="designation">{email}</p> </div> </div> </div> ) } export default UsersC:\react-js\myreactdev\src\components\Loader.js
//C:\react-js\myreactdev\src\components\Loader.js import React, { } from "react"; function Loader() { return ( <div className="container"> <div className="row "> <div className="col d-flex justify-content-center"> <div class="spinner-border spin" role="status"> <span class="visually-hidden">Loading...</span> </div> </div> </div> </div> ) } export default LoaderC:\react-js\myreactdev\src\components\End.js
//C:\react-js\myreactdev\src\components\End.js import React, { } from "react"; function End() { return ( <p style={{ textAlign: "center" }}> <b>End</b> </p> ) } export default Endreact-js\myreactdev\src\App.css
//react-js\myreactdev\src\App.css body{margin-top:20px; background:#eee; } .single_advisor_profile { position: relative; margin-bottom: 50px; -webkit-transition-duration: 500ms; transition-duration: 500ms; z-index: 1; border-radius: 15px; -webkit-box-shadow: 0 0.25rem 1rem 0 rgba(47, 91, 234, 0.125); box-shadow: 0 0.25rem 1rem 0 rgba(47, 91, 234, 0.125); } .single_advisor_profile .advisor_thumb { position: relative; z-index: 1; border-radius: 15px 15px 0 0; margin: 0 auto; padding: 30px 30px 0 30px; background-color: #3f43fd; overflow: hidden; } .single_advisor_profile .advisor_thumb::after { -webkit-transition-duration: 500ms; transition-duration: 500ms; position: absolute; width: 150%; height: 80px; bottom: -45px; left: -25%; content: ""; background-color: #ffffff; -webkit-transform: rotate(-15deg); transform: rotate(-15deg); } @media only screen and (max-width: 575px) { .single_advisor_profile .advisor_thumb::after { height: 160px; bottom: -90px; } } .single_advisor_profile .single_advisor_details_info { position: relative; z-index: 1; padding: 30px; text-align: right; -webkit-transition-duration: 500ms; transition-duration: 500ms; border-radius: 0 0 15px 15px; background-color: #ffffff; } .single_advisor_profile .single_advisor_details_info::after { -webkit-transition-duration: 500ms; transition-duration: 500ms; position: absolute; z-index: 1; width: 50px; height: 3px; background-color: #3f43fd; content: ""; top: 12px; right: 30px; } .single_advisor_profile .single_advisor_details_info h6 { margin-bottom: 0.25rem; -webkit-transition-duration: 500ms; transition-duration: 500ms; } @media only screen and (min-width: 768px) and (max-width: 991px) { .single_advisor_profile .single_advisor_details_info h6 { font-size: 14px; } } .single_advisor_profile .single_advisor_details_info p { -webkit-transition-duration: 500ms; transition-duration: 500ms; margin-bottom: 0; font-size: 14px; } @media only screen and (min-width: 768px) and (max-width: 991px) { .single_advisor_profile .single_advisor_details_info p { font-size: 12px; } } .single_advisor_profile:hover .advisor_thumb::after, .single_advisor_profile:focus .advisor_thumb::after { background-color: #070a57; } .single_advisor_profile:hover .single_advisor_details_info, .single_advisor_profile:focus .single_advisor_details_info { background-color: #070a57; } .single_advisor_profile:hover .single_advisor_details_info::after, .single_advisor_profile:focus .single_advisor_details_info::after { background-color: #ffffff; } .single_advisor_profile:hover .single_advisor_details_info h6, .single_advisor_profile:focus .single_advisor_details_info h6 { color: #ffffff; } .single_advisor_profile:hover .single_advisor_details_info p, .single_advisor_profile:focus .single_advisor_details_info p { color: #ffffff; } .spin { width: 3rem; height: 3rem; }react-js\myreactdev\public\index.html
//react-js\myreactdev\public\index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Web site created using create-react-app" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <title>React App</title> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"/> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html>Run C:\react-j\myreactdev>npm start
http://localhost:3000/