Приложение для отслеживания бюджета на React js для начинающих

RedDeveloper
18.03.2022 15:49
Приложение для отслеживания бюджета на React js для начинающих

Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека совершенным", здесь я хотел бы добавить "Perfect" в начале, тогда цитата будет звучать так: "Совершенная практика делает человека совершенным". Я полный новичок в React js и недавно я сделал приложение для отслеживания бюджета на React.

Будучи полным новичком, я вспомнил цитату, упомянутую ранее, и вместо того, чтобы следовать учебнику YouTube, я связал свою руку, чтобы написать свой первый в жизни проект на React. Несмотря на то, что проект прост и легок в создании, для новичка создать такой проект слишком сложно. Если вы совсем новичок и хотите создать проект, то приложение для отслеживания бюджета - лучший вариант. В этой статье я расскажу вам о своем проекте.

Приложение для отслеживания бюджета на React

Создание приложения

Первым шагом для создания любого проекта react является создание проекта react. Для этого вы можете следовать следующим фрагментам кода. Я назову проект budget_calculator.

Npx create-react-app budget_calculator

Как только вы создали react-приложение, запустите его, чтобы убедиться в его работоспособности.

Npm start

Создание компонентов

Поскольку наше приложение принимает данные от пользователя и отображает транзакцию, как показано на рисунке. Нам нужно создать папку с двумя компонентами. Я назвал одну из них form для секции ввода, а вторую main для секции отображения или транзакции. Вы можете назвать их по своему усмотрению.

Добавьте компонент

На этом этапе я создал разные компоненты по отдельности, так как мне нравилось четко разделять вещи, чтобы в них было легко ориентироваться и понимать. Давайте подумаем о главном компоненте, в этом компоненте будут отображаться доходы, расходы и остаток. Также в этом разделе будет отображаться транзакция и навигационная ссылка или кнопка для создания формы, верно?

В соответствии с этой концепцией я создал компоненты Budget, Balance, Transaction и Footer. Бюджет является главным компонентом в разделе main, так как он объединяет все компоненты для правильного отображения. Аналогично, компонент Balance будет отображать общие доходы,расходы и общий остаток. Также компонент Transaction будет отображать все транзакции, добавленные пользователем через раздел формы. Наконец, компонент Footer будет использоваться для перехода к следующему разделу формы, чтобы предоставить пользователю раздел ввода.

Далее, для компонента формы компонент AddNew будет выступать в качестве родительского компонента для компонентов Enter и Select. Компонент Select будет содержать элемент выбора, является ли вновь добавленная транзакция доходом или расходом. Кроме того, он будет отображать категорию соответствующего дохода или расхода в соответствии с выбором, сделанным пользователем. Аналогично, компонент Enter будет содержать секцию ввода суммы и описания транзакции. На этом мы закончим эту часть.

Создание дизайна пользовательского интерфейса

Следующая задача - разработать дизайн шаблона или интерфейса. Прежде всего, я разработал его для главного компонента, где отображаются доходы, расходы и транзакции. Вы можете разработать дизайн в соответствии с вашими идеями и творческими способностями. Кроме того, вы можете черпать вдохновение из любого дизайна, доступного в Интернете. Здесь я хотел бы предложить вам сосредоточиться на изучении реакции, а не дизайна.
Я создал и связал отдельные CSS для каждого компонента. Я упомяну конечную структуру файлов и папок моего проекта.

//index.cssbody
{
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', '
Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue '

, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}code

{
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New '





, monospace;
}//App

.css


.App-logo {
height: 40vmin;
pointer-events: none;
}@media

(prefers-reduced-motion: no-preference) {.








App-logo {
animation: App-logo-spin infinite 20s linear;
}}


.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}}

.App-link {










color: #61dafb;
}@keyframes

App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}}//Balance

.css
.income {
display: inline-block;
margin-right: 50%;
}

.expense {
display: inline-block;
}//Budget

.css

.full {
width: 70%;
height: 80%;
background-color: bisque;
border: 5px solid black;
margin: auto;
}

.hr {
color: black;
}.








App {
text-align: center;
}//Footer

.css

.btn {
background-color: #0c80df;
border: none;
color: white;
padding: 16px 32px;
margin: 2px 0 10px ;
}//Transaction
.css

.in {
color: green;
}

.exp {
color: red;
}

.title, amount {
display: inline-block;
margin: 0;
padding: 1rem;
}.



title {
text-align: left;
}.








amount {
text-align: right;
float: right;
padding-right: 10em;
}//AddNew

.css
.box {
width: 70%;
height: 80%;
background-color: bisque;
border: 5px solid black;
margin: auto;
}

.text {
text-align: center;
}//Enter
.css
.save {
background-color: #0cdf5d;
border: none;
color: white;
padding: 16px 32px;
margin: 10px 10px 10px;
}

.close {
background-color: #6a6e6c;
border: none;
color: white;
padding: 16px 32px;
margin: 10px 10px 10px;
}//Select

.css

.select1 {

display: inline-block;
margin: 5px;
}

.select2 {
display: inline-block;
margin: 5px 0 0 20px;
}

Приступим к части кодирования приложения для отслеживания бюджета на React

Прежде всего, я устанавливаю react-router-dom для навигации. Затем я импортирую BrowserRouter в компонент index.js. Аналогично, я импортирую Route и Routes в App js для управления маршрутом проекта. Я сделал компонент Budget родительским, а компонент AddNew мог перемещаться по ссылке '/add'.

Npm install react-router-dom
//Index.jsimport
React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';

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

// Если вы хотите начать измерять производительность в своем приложении, передайте функцию//
для логирования результатов (например: reportWebVitals(console.info))
// или отправьте в конечную точку аналитики. Подробнее:
https://bit.ly/CRA-vitalsreportWebVitals();

//App.jsimport

Budget from './components/main/Budget';
import { Route, Routes } from 'react-router';
import AddNew from './components/form/AddNew';
import './App.css';


function App() {

return (
<>

<Routes>
<Route path = '/' element = {<Budget />} />
<Route path = '/add' element = {<AddNew />} />
</Routes>
</>
);
}export

default App;

Компонент AddNew

Компонент AddNew имеет функциональность для выбора и ввода суммы пользовательских транзакций. В этом компоненте я импортировал хук useState и использовал его для создания различных переменных состояния. Состояние option используется для проверки того, является ли транзакция, совершенная пользователем, доходом или расходом. Аналогично, состояния income и expense создаются для хранения типа совершенной транзакции. Аналогично, состояние amount создается для хранения суммы совершенных транзакций. В то время как деталь содержит описание транзакций.

Здесь я импортировал хук useFecth. Это пользовательский хук, и я объясню его позже в статье. Функция handleBudget будет выполняться при отправке формы из компонента enter. Это позволит загрузить и сохранить все введенные пользователем данные.

//AddNew.jsimport
Enter from "./Enter";
import Select from "./Select";
import './AddNew.css';
import { useState, useEffect } from 'react';
import useFetch from ".../.../useFetch";


const AddNew = () => {

const [budget, setBudget] = useFetch('budget', []);

const [option, setOption] = useState('income');
const [income, setIncome] = useState('Зарплата')
const [expense, setExpense] = useState('Образование')
const [amount, setAmount] = useState('')
const [detail, setDetail] = useState('')


const handleBudget = (e) => {
e
.preventDefault();


let budgets = {
option,
amount,
detail,
income: option == 'income' ? income : ''







, expense:option != 'income' ? расход : '
' }
setBudget([...budget, budgets]);
setOption('income ');



setIncome('Salary ');




setExpense('Education ');





setAmount( '')






; setDetail('');

}


// useEffect(() => {
// // dataToNew(budget);
// if (budget?.length){
// localStorage.setItem('budget', JSON.stringify(budget));
// // }

// }, [budget])


return (
<>
<> <div className="text">





<h2>Добавить новый бюджетный список</h2>

<div className="box">








<Select option = {option} setOption = {setOption} income = {income} expense = {expense} setIncome = {setIncome} setExpense = {setExpense} />
<Enter amount = {amount} setAmount = {setAmount} detail = {detail} setDetail = {setDetail} handleBudget = {handleBudget} />

</div>

</div>
</>
)
}export

default AddNew;

//Enter.jsimport
'./Enter.css';
import { NavLink } from 'react-router-dom'


; const Enter = ({ amount, setAmount, detail, setDetail, handleBudget}) => {


return (
<>
<form onSubmit = {handleBudget}}

<h2>Enter Amount</h2>

<input type="number
" placeholder='Enter Amount
' className='amount_field
' onChange = {(e) => setAmount(parseInt(e.target.value))}
value = {amount}
required
/>

<h2>Enter Details</h2>

<input type="text
" placeholder='Enter Details
' className='details_field
' onChange = {(e) => setDetail(e.target.value)}
value = {detail}
required
/>

<br />

<NavLink to = '/'><button className='close'>Cancel</button></NavLink>.








<button type="submit" value="Save" className='save'>Save</button>

</form>


</> </>
)
}export

default Enter;

//Select.jsimport
'./Select.css';
import { useEffect } from 'react';

const Select = ({ option, setOption, income, setIncome, expense, setExpense}) => {


const datas = [
{
id : 1,
income : "Зарплата
", expense : "Образование
" },
{
id : 2,
доход : "Акции
", расход : "Транспорт
" },
{
id : 3,
доход : "ПИФ
", расход : "Мебель
" }
]


useEffect(() => {
setIncome(datas[0]?.income)
setExpense(datas[0]?.expense)
}

, [option])


return (
<div className='data'>












<select className='select1' value= {option} onChange = {(e) => setOption(e.target.value)}>
<option value='income'>Income</option>
<option value='expense'>Expense</option>


</select>

{(option == 'income') ?

<select className='select2' value = {income} key = {datas.id}onChange = {(e) => setIncome(e.target.value)}>

{datas.map((data) => {
return (
<option key = {data.id} value = {data.income} >{data.income}</option>
)
})}
</select>

:

<select className='select2' value = {expense} key = {datas.id} onChange = {(e) => setExpense(e.target.value)}>

{datas.map((data) => {
return (
<option key = {data.id} value = {data.expense}>{data.expense}</option>
)
})}
</select>
}
</div>
)
}export

default Select;

Компонент бюджета

Этот компонент является родительским компонентом главного раздела. Он состоит из тега заголовка для отображения калькулятора бюджета. Кроме того, у него есть дочерние компоненты - Баланс, Транзакция и Нижний колонтитул.

import './Budget.css';
import Balance from './Balance';
import Transaction from './Transaction';
import Footer from './Footer';

const Budget = () => {

return (
<div className="App">





<h2>Калькулятор бюджета</h2>
<div className="full">
<Balance />
<hr className='hr' />
<Transaction />
<Footer />
</div>
</div>
)
} }export

default Budget;

Компонент баланса

Компонент Balance извлекает данные из useFetch в переменную состояния value. Значение используется для отображения внутри хука useEffect для получения соответствующего ввода пользователя. Такие данные отображаются в разделе доходов или расходов. Сумма будет рассчитана, а остаток будет отображен в разделе Total Balance.

//Balance.jsimport
'./Balance.css';
import useFetch from '.../.../useFetch';
import { useState, useEffect } from 'react';


const Balance = () => {

const [ value ] = useFetch('budget', []);
const [incomeAmount, setIncomeAmount] = useState(0);
const [expenseAmount, setExpenseAmount] = useState(0);


let total_income = 0;
let total_expense = 0;

useEffect(() => {
{value.map((d) => {
if (d.option === 'income' && d.expense === '') {
total_income += d.amount
setIncomeAmount(total_income)
}else{
total_expense += d.amount
setExpenseAmount(total_expense)
}
})}
}, [value])


return (
<div className="top">




<div className="total">





<h3>Общий баланс : Rs {incomeAmount - expenseAmount } </h3>
</div>
<div className="rem">


<div className="income">



<h3>Income</h3>
<p>Rs {incomeAmount} </p>
</div>
<div className="expense">

<h3>Expense</h3>
<p>Rs {expenseAmount}</p>
</div>
</div>
</div>
)
}export

default Balance;

//Transaction.jsimport
'./Transaction.css';
import useFetch from '../../useFetch';

const Transaction = () => {

const [ Value ] = useFetch('budget', []);


return (
<div className="middle">








<h2 style = {{color : 'blue' }}>Transaction</h2>

{Value.map((v) => {
return (

<> {v.option === 'income' ?
<div className="in">




<h3 className='title'>{v.income}</h3>
<p className='amount'>Rs {v.amount}</p>
</div>
:
<div className="exp">




<h3 className='title'>{v.expense}</h3>
<p className='amount'>Rs {v.amount}</p>
</div>
}
</>
)
})}
<hr />
</div>
)
}export

default Transaction;

//Footer.jsimport

'./Footer.css';
import { NavLink } from 'react-router-dom';

const Footer = () => {
return (
<div className="footer">






<NavLink to = '/add'>
<button className='btn'>Add New</button>
</NavLink>
</div>
)
} } export

default Footer;

Пользовательский хук UseFetch

Этот хук был создан в папке src. Основная цель хука - сохранить ввод пользователя в локальном хранилище и получить каждое значение транзакции для дальнейшего использования. Localstorage.setItem сохраняет вводимые данные в локальном хранилище, а getStorageValue используется для получения данных из локального хранилища.

import { useState, useEffect } from "react";

function getStorageValue(key, []) {

const saved = localStorage.getItem(key);
const initial = JSON.parse(saved);
return initial || [];
}export

const useFetch = (key, []) => {
const [value, setValue] = useState(() => {
return getStorageValue(key, []);
});

useEffect(() => {
// сохранение входного имени
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);

return [value, setValue];
};

export default useFetch;

Заключение

На этом мы подошли к концу руководства по созданию приложения для отслеживания бюджета в React. Мы рассмотрели почти все моменты, необходимые для создания приложения. Надеюсь, вы создали свой бюджетный калькулятор. Если у вас возникли какие-либо проблемы, вы можете посетить мойрепозиторийGitHub или задать свой вопрос прямо в разделе комментариев, я буду рад помочь вам.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?

20.08.2023 18:21

Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в 2023-2024 годах? Или это полная лажа?".

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией

20.08.2023 17:46

В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.

Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox

19.08.2023 18:39

Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в частности, магию поплавков и гибкость flexbox.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest

19.08.2023 17:22

В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для чтения благодаря своей простоте. Кроме того, мы всегда хотим проверить самые последние возможности в наших проектах!

Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️

18.08.2023 20:33

Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий их языку и культуре.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL

14.08.2023 14:49

Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип предназначен для представления неделимого значения.