6 dk, tahmini okuma süresi

Basit Bir Proje Ile Yeni React-Redux Ogrenelim

En Son Güncelleme: 1 Temmuz, 2022

Projeleriniz yeterince küçükken, reactjs'te state yönetmek per de zor değil. Projeleriniz büyüdükçe, state'i ebeveyne ve ya çocuğa göndermek sadece kirlilik yaratıyor ve kodunuzu okumayı ve anlamayı zorlaştırıyor. Bu noktada Redux günü kurtarmaya geliyor. Hadi başlayalım!

Bu metinde react ve react-redux kullanarak basit bir e-ticaret uygulaması oluşturacağız. Bu şekilde anlamanın daha kolay olacağına inanıyorum. Üzerinden geçerken kod parçalarını da açıklayacağım. Bir yerde sıkışıp kaldığınızı düşünüyorsanız ve bir hata görürseniz bu repository'i ziyaret edebilirsiniz.

§Projemizi Oluşturalım

Basit bir npx komutu ile projemize başlayacağız.

npx create-react-app react-redux-project

Proje kurulumu tamamlandığında, devam edip kullanacağımız paketleri kurabiliriz. Elbette react-redux kurmamız ve yönlendirmeyi (routing)react-router-dom ile yapmamız gerekiyor.

npm i react-router-dom react-redux

§Başlangıç ​​Projesini Temizle

Öncelikle projemizin hiçbir yerinde kullanmayacağımız için logoyu silelim. App.css, App.js ve App.test.js'yi de gönül rahatlığıyla silebilirsiniz. Artık index.js dosyasındaki sarmalayıcı div (wrapper div) dışındaki her şeyi silebiliriz. İşimiz bittiğinde index.js dosyamız şöyle görünmelidir:

import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import reportWebVitals from './reportWebVitals'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <div>Test</div> </React.StrictMode> ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();

If everything has gone well up to this point, when you execute the command bash npm start you should see the Test on your screen now. Now we are ready to write our code.

Buraya kadar her şey yolunda gittiyse, bash npm start komutunu çalıştırdığınızda, şimdi ekranınızda Test yazılı bir metin görmelisiniz. Artık kodumuzu yazmaya hazırız.

§Proje Detayları ve Planlama

Tipik bir e-ticaret web sitesinin iyi bir örnek olduğunu düşünüyorum. Tipik redux işlevselliğini kullanarak durumu ele almanın ne kadar kolay olduğunu göreceğiz. Ana sayfamızda 9 öğeyi grid içinde tutacağız. Her öğenin, seçilen öğeyi sepetimize eklememizi sağlayacak bir düğmesi olacaktır. Sepetimizde bulunan ürünlerin miktarını navbar üzerinde görebileceğiz. Sepete bağlantı sayfasında basit bir badge (rozet) ile sayımı sürdüreceğiz.

Kişisel bir not, redux'ı basit bir şekilde işlevsel hale getirmek için gereken başlangıç kodu bile eskiden çok fazlaydı. Şahsen elimden geldiğince redux kullanmaktan kaçınırdım ama şimdi çok daha basit olduğunu göreceksiniz. Tabii ki, ihtiyacınız olup olmadığına karar vermek size kalmış.

src klasöründe pages ve components klasörleri oluşturun. Sayfalarımızı ve bileşenlerimizi bu klasörlerde oluşturacağız.

§Store

Store'u tüm durumların ve durumumuzu ayarlama (state setter) mantığının bulunduğu yer olarak düşünebilirsiniz. Store'u bu şekilde ayrı tutmak istediğimiz herhangi bir bileşenden store'a ulaşmamıza olanak sağlıyor. Durumu değiştirmenin tek yolu, üzerinde bir action göndermektir (dispatch).

src klasörünün içinde app adlı bir klasör oluşturun. Klasörün içinde store.js dosyası oluşturun. Gördüğünüz gibi bu dosyanın kodu çok basit:

import { configureStore } from '@reduxjs/toolkit' import shopReducer from '../slice/shopSlice' export default configureStore({ reducer: { shop: shopReducer }, })

Henüz reducer'ımız ve slice'ımız olmadığı için store'u oluşturduktan sonra bir hata göreceksiniz. Yakında oluşturacağımız için şimdilik endişelenmeyin.

Mağazamız için store oluşturduk. Artık bir şeylerin gerçekleşmesi için gereken tüm mantığı halledebiliriz.

§Slice Oluşturalım

Redux toolkit ile bir slice oluşturmak çok basit. Daha önce bu kadar basit değildi ve bence insanların (ben dahil) redux kullanmaktan kaçınmasının ana nedeni buydu. Aksiyonlar, aksiyn türleri vb. yaratmak zorundaydık. Çok can sıkıcıydı.

Bir dilim oluşturmak için createSlice işlevini kullanacağız. Bu fonksiyon bir başlangıç ​​durumu, gönderilecek reducer fonksiyonları ve dilimimiz için bir isim kabul eder. Bu kadar! Redux toolkit, aksiyon yaratıcıları ve türleri oluşturmayı kendi hallediyor.

src klasörünün içinde shopSlice adında yeni bir dosya oluşturacağız. Kodun çok açıklayıcı olduğuna inanıyorum, ancak anlaşılmasını kolaylaştırmak için yorumlar da ekledim. Bu dosyanın tam kodu burada:

import { createSlice } from '@reduxjs/toolkit' // bu state bizim başlangıç ​​durumumuz olarak kullanılacaktır (initial state). const state = { // Sepetimiz başlangıçta boş cart: [], // Ana sayfamızda göstereceğimiz array // Renkleri sadece satmak için sergileyeceğimiz ürünler olarak kullanacağız. items: [ { id: 1, name: "cyan", price: 10.99}, { id: 2, name: "teal", price: 12.99}, { id: 3, name: "yellow", price: 14.99}, { id: 4, name: "lime", price: 12.99}, { id: 5, name: "pink", price: 6.99}, { id: 6, name: "purple", price: 2.99}, { id: 7, name: "turquoise", price: 4.99}, { id: 8, name: "red", price: 18.99}, { id: 9, name: "gold", price: 20.99}, ] } export const shopSlice = createSlice({ name: 'shop', initialState: state, reducers: { addItemToCart: (state, action) => { // Önce ürünün sepette olup olmadığını kontrol edelim let item = state.cart.filter(x => x.id === action.payload)[0] // Sepette ürünümüz varsa, miktarını artıracağız. if(item) { let newQuantity = item.quantity + 1; // Artan miktarda yeni öğemizi oluşturmak için spread operatörünü (...) kullanıyoruz item = {...item, quantity: newQuantity} let i = state.cart.findIndex(i => i.id === action.payload) // Array.slice() metoduyla kolayca bu mantığı da oluşturabiliriz // Miktarı değiştiriyoruz // Tekrar spread opeator kullanarak state'imizi güncellemiş oluyoruz state.cart = [...state.cart.slice(0,i), item,...state.cart.slice(i+1)] } // Sepetimizde ürün yoksa else { // Öğeyi almamız ve yeni bir anahtar, miktar eklememiz gerekiyor let i = state.items.filter(x => x.id === action.payload)[0]; i = {...i, quantity: 1 }; // En son olarak da sepete ekliyoruz state.cart = [...state.cart, i] } }, removeFromCart: (state, action) => { // Filtreleyerek öğeyi çıkarıyoruz state.cart = state.cart.filter(i => i.id !== action.payload) }, // Sepetimizde ihtiyaç duyacağımız eksiltme mantığı decrementQuantity: (state, action) => { // forEach yöntemini kullanarak dizide dolaşın ve Öğenin miktarını azaltın // Gördüğünüz gibi, artırma yönteminde yaptığımız gibi, mutasyona uğramadan yeni // bir dizi oluşturmamız gerekmiyordu. Elbette, sepetimize ürün eklemek için buradaki // gibi bir yöntem kullanmak mümkün. state.cart.forEach(i => { if(i.id === action.payload) { if(i.quantity > 1) { i.quantity -= 1; }else{ // Sadece bir tane varsa öğeyi kaldır state.cart = state.cart.filter(i => i.id !== action.payload) } } }) }, clearCart: (state) => { // Sepeti boşalt state.cart = []; } }, }) // State'e ulaşmak için seçiciler (selectors) kullanılacaktır. export const selectCart = (state) => state.shop.cart; export const selectItems = (state) => state.shop.items; // Son olarak, gönderilecek tüm aksiyonları dışa aktarıyoruz (export). export const { addItemToCart, removeFromCart, decrementQuantity , clearCart } = shopSlice.actions // Mağazada kullanılmak üzere reducre'ımızı ihraç ediyoruz. export default shopSlice.reducer

Basit e-ticaret web sitemizi çalıştırmak için gereken tüm kod buydu. Yukarıdaki yorumlarda da yazdığım gibi mantığı mutasyona uğratarak değiştirebilirsiniz. Redux bizim için mantığı ilgilendiğinden, bu yöntem artık tamamen güvenli.

§Provider Wrapper

index.js dosyamızda Provider'ı react-redux'dan içe aktarmamız gerekiyor. Uygulamamızı Provider ile sarmak store'u görünür kılar ve store ile etkileşim kurmamıza olanak tanır. Kod da çok basittir, bu son eklemeyle birlikte index.js dosyamız şöyle görünecektir:

import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import reportWebVitals from './reportWebVitals'; import store from './app/store'; import { Provider } from 'react-redux'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <Provider store={store}> <div>Test</div> </Provider> </React.StrictMode> ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();

§Rotaları Oluşturmaya Başlayın

Yönlendirmeyi react-router-dom paketi yardımıyla halledeceğiz. Bu paket, sayfalarımız için bir sarmalayıcı düzeni kullanmamıza izin verecek ve bu şekilde, kendi sayfalarımıza yapılan bağlantıların layoutta (sayfa düzenimizde) görüneceğini göreceksiniz. Tüm sayfayı değil, yalnızca farklı olan, değişmesi gereken kısımlarını yeniden yükleyeceğiz. Yönlendirme konusunda daha derine inmeyeceğim, bununla ilgili daha fazla bilgi edinmek istiyorsanız buradaki dokümantasyonu okumanızı öneririm.

Router işlevselliğimizi test etmek için temel, basit sayfalar ve gezinme çubuğumuzu oluşturabiliriz. Devam edelim ve pages klasörü içinde Cart.jsx ve Home.jsx dosyaları oluşturalım. Şimdiye kadar bu sayfalarda havalı bir şeye ihtiyacımız yoktu. Burada sadece bir react bileşeni oluşturabilirsiniz. Bu sayfalar daha sonra sayfalarımızda kullanacağımız tüm bileşenleri içe aktarmak için kullanılacaktır. Sayfalarımızın ve bileşenlerinin bu şekilde ayrılması, kodumuzun daha sonra anlaşılmasını kolaylaştırıyor.

Sayfaları oluşturduysanız, artık navbar klasörümüzü oluşturabiliriz. Bu klasörde bir Navbar.jsx dosyası ve bir Navbar.css dosyası oluşturacağız. Link ve Outlet olmak üzere iki öğeyi (bunlara ne diyeceğimizi tam olarak bilemiyorum) içe aktaracağız. Link, dahili bağlantı için a etiketlerinin yerini alacak ve bize gayet akıcı bir yönlendirme deneyimi sağlayacaktır. Bu şekilde, burada Navbar'ımız gibi aynı kalan parçaları yeniden yüklemeyeceğiz. Outlet, sarılmış bileşenlerin Navbar bileşenimizde nerede görüneceğini belirlemek için kullanılacaktır. Tanımlanan işlevselliği çalışırken görmek, daha iyi anlamamıza yardımcı olacaktır.

Navbar'ımıza, sepetimizdeki ürünlerin miktarını bize gösterecek basit bir rozet benzeri sayaç eklemek istedim. Bunu başarmak için bir selector kullanacağız. Sepeti seçeceğiz ve bir useEffect kancasındaki (hook) öğelerin miktarını hesaplayacağız. Bu işlevselliği ve mantığı redux kullanarak oluşturabiliriz. Ben sadece bu şekilde yaptım. Kendiniz için basit bir meydan okuma oluşturmak ve redux bilginizi test etmek istiyorsanız, mantığı redux kullanarak oluşturmaktan çekinmeyin.

Bu kodun anlaşılmasını kolaylaştırmak için aşağıya bazı yorumlar ekledim. Navbar'ımızın bitmiş kodu şöyle görünecek:

import React, { useState, useEffect } from 'react' import { Outlet, Link } from 'react-router-dom' import './Navbar.css' import { useSelector } from 'react-redux'; import { selectCart } from '../../slice/shopSlice'; const Navbar = () => { const cart = useSelector(selectCart) const [cartQuantity, setCartQuantity] = useState(0); useEffect(() => { if(cart.length >= 0){ let n = 0; cart.map(x => n += x.quantity) setCartQuantity(n) } }, [cart, cartQuantity]) return (<> <div className='navbar-wrapper'> <Link className='nav-link' to="/">Home</Link> <Link className='nav-link' to="/cart">Cart <span className='length-badge'>{cartQuantity}</span></Link> </div> {/* Outlet'i burada kullanmak, Navbar'ımızla saracağımız bileşenlerin burada görünmesini sağlayacaktır. */} <Outlet /> </>) } export default Navbar

Now we can style our Navbar. Of course feel free to use your own style if you won't like mine, Imust admit I'm not the best web designer. Now in Navbar.css file add this code below:

Artık Navbar'ımızı şekillendirebiliriz. Tabii ki benim tarzımı beğenmediyseniz kendi css değerlerinizi kullanmakta özgürsünüz, itiraf etmeliyim ki ben pek de iyi bir web tasarımcısı değilim. Şimdi Navbar.css dosyasında aşağıdaki kodu ekleyin:

.navbar-wrapper { height: 100px; text-align: end; padding: 20px 40px; font-size: 1.4rem; position: fixed; left:0; right: 0; font-weight: bold; background: linear-gradient(45deg, rgba(255,255,255,0), rgba(255, 255, 255, .1)); z-index: 100; } .nav-link { color: rgb(96, 1, 1); text-decoration: none; margin-right: 40px; font-size: 1.8rem; transition: 0.2s; } .nav-link:hover { color: rgb(130, 62, 62); } .length-badge { font-size: 0.9rem; }

Artık Navbar'ımızı değiştirmemiz gerekmeyecek, böylece artık index.js dosyasını da işleyebilir ve yönlendiricimizi test edebiliriz. Yönlendiricimizin tam kodu aşağıdaki gibi:

import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import reportWebVitals from './reportWebVitals'; import store from './app/store'; import { Provider } from 'react-redux'; import { BrowserRouter, Routes, Route } from 'react-router-dom'; import Navbar from './components/navbar/Navbar'; import Home from './pages/Home'; import Cart from './pages/Cart'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <Provider store={store}> <BrowserRouter> <Routes> <Route path="/" element={<Navbar/>}> <Route index element={<Home />} /> <Route path="cart" element={<Cart/>} /> </Route> </Routes> </BrowserRouter> </Provider> </React.StrictMode> ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();

index.css için tam kod da burada:

* { box-sizing: border-box; padding: 0; margin: 0; } img { width: 100%; } body { 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; min-height: 100vh; } code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; }

Buraya kadar her şey yolunda gittiyse, navigasyon çubuğumuzdaki bağlantıları kullanarak oluşturduğumuz 2 sayfayı ziyaret edebilirsiniz.

§Artık Bileşenlerimizin Geri Kalanını Oluşturabiliriz

Ana sayfamızda kullanacağımız bileşenleri oluşturmaya başlamanın daha mantıklı olacağını düşünüyorum. Kullanıcıya o anda hangi sayfada olduğunu söyleyen bir banner'a ihtiyacımız var ve mevcut tüm satılacak öğeleri kullanıcıya göstermemiz gerekiyor. Bu başlığı sepet sayfasının içinde kullanabiliriz, böylece metni göstermek için bir destek olarak alan bir bileşen oluşturabiliriz. Banner'ı oluşturarak başlayalım.

components klasörünün içinde bir banner klasörü oluşturun. Bu klasörde Banner.jsx ve Banner.css dosyalarını oluşturacağız. Bu dosyaların her ikisi de çok basit ve anlaşılması kolaydır:

// Banner.jsx file import React from 'react' import './Banner.css' const Banner = ({text}) => { return ( <div className='banner-wrapper'> <p className='banner-text'>{text}</p> </div> ) } export default Banner .banner-wrapper { height: 300px; background: teal; } .banner-text { font-size: calc(32px + 2vw); margin-left: 140px; padding-top: 110px; color:rgb(238, 71, 71); text-decoration: under; font-weight: bold; text-shadow: 2px 2px 2px rgb(1, 34, 70); }

Artık bu halledildiğine göre, eşyalarımızı gösterecek bir bileşen düşünebiliriz. Bu işlevsellik için aslında iki bileşene ihtiyacımız olacak. Öğeleri alacak bir bileşen ve öğeler dizisindeki her öğe için oluşturabileceğimiz başka bir bileşen.

Bileşenlerin içinde items klasörü oluşturalım ve klasörün içinde Items.jsx ve Items.css dosyalarını oluşturalım. Burada da sadece seçici işlevine ihtiyacımız var. Öğelerimizi bu bileşende alacağız. Bu bileşenin tam kodu aşağıdaki gibi:

import React from 'react' import { useSelector } from 'react-redux' import { selectItems } from '../../slice/shopSlice' import './Items.css' const Items = () => { const items = useSelector(selectItems); return ( <div className='items-container'> </div> ) } export default Items

Ve bu bileşenin o kadar da korkunç görünmemesi için css dosyasının kodu:

.items-container { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: center; max-width: 960px; margin: -40px auto 260px; background: rgb(221, 254, 255); box-shadow: 2px 2px 32px 2px rgb(0, 0, 0); padding: 40px; border-radius: 10px; }

Basit, değil mi?

Artık öğelerimizi aldığımıza göre, onları başka bir bileşen kullanarak eşleyebiliriz. Bu çok basit bir işlem olduğu için bir bileşen kullanmamıza gerek yok ama kodumuzu temiz tutmak istiyoruz tabii ki. Devam edin ve components klasörünün içinde item klasörü oluşturun. Bu klasörün içinde Item.jsx ve Item.css dosyaları oluşturun. Item.jsx dosyamızda item bilgilerini bir prop olarak alacağımız ve itemlerimizi göstereceğimiz bir component oluşturacağız. Seçilen ürünü sepetimize eklemek için her ürün için bir düğme ekleyeceğiz. Bu buton ile bir eylem göndereceğiz ve sepetimizi bu şekilde manipüle edeceğiz.

Item.jsx dosyamızın tam kodu aşağıdaki gibidir:

import React from 'react' import './Item.css' import { useDispatch } from 'react-redux' import { addItemToCart } from '../../slice/shopSlice' const Item = ({ name, id, price}) => { const dispatch = useDispatch(); return ( <div className='item-cart'> <div className='color-box' style={{background: name}}></div> <p className='p-name'>{name}</p> <p className='p-price'>{price} $</p> <button onClick={() => dispatch(addItemToCart(id))} className='add-button'>Add to Cart</button> </div> ) } export default Item

Şimdi bileşenimizi biraz güzelleştirelim, Item.css dosyasının kodu da burada:

.item-cart { max-width: 260px; min-width: 200px; margin: 20px; box-shadow: 2px 2px 21px 2px rgb(180, 241, 180); padding: 20px; border-radius: 10px; background: white; } .color-box { padding: 80px; } .p-name { margin-top: 20px; margin-bottom: 10px; color: rgb(16, 57, 99); text-transform: capitalize; font-size: 1.45rem; } .p-price { color: rgb(116, 0, 73); } .add-button { margin-top: 10px; border: none; width: 100%; padding: 10px; background-color:hsl(160, 100%, 75%); border-radius: 15px; transition: .2s; font-size: 1.2rem; box-shadow: 2px 2px 2px 2px teal; } .add-button:hover { background-color: hsl(160, 100%, 24%); color: white; cursor: pointer; } .add-button:active { box-shadow: none; }

This was all the components we need for our home page. So the full code the for our component is here: Ana sayfamız için ihtiyacımız olan tüm bileşenler buydu. Yani bileşenimiz için tam kod burada:

import React from 'react' import Banner from '../components/banner/Banner' import Items from '../components/items/Items' const Home = () => { return (<> <Banner text="Home"/> <Items /> </>) } export default Home

§Hadi Sepeti Halledelim

Oluşturduğumuz banner bileşenini bu sayfa için de kullanabiliriz. Bu, bileşenlerle çalışmayı sevmemin nedenlerinden biri. Zaten bileşen tabanlı çerçeveleri (framework) bu kadar popüler yapan da zaten bu.

Bu nedenle, sepetimizdeki öğelerin görüntülenmesi ve kaldırılması vs. mantığına odaklanacağız. Bileşendeki her şeyi halledeceğiz. components klasörünün içinde inCart adlı bir klasör oluşturun. Bu klasörün içinde InCart.jsx ve InCart.css dosyaları oluşturun. Bu bileşen henüz en önemli olanıdır.

Sepette ürün yoksa, kullanıcıya bir metin ve bir bağlantı göstereceğiz, böylece kolayca alışverişe dönebilirler. Aksi takdirde, öğelerimizi liste öğeleri olarak göstereceğiz. Sepetteki bir öğenin miktarını artırmak, azaltmak için düğmeler ekleyeceğiz. Bir öğeyi doğrudan kaldırmak için bir düğme ve ayrıca tüm öğeleri kaldırarak sepeti temizlemek için bir düğme ekleyeceğiz. Bu bileşenin tam kodu aşağıdaki gibi:

import React from 'react' import './InCart.css' import { useDispatch, useSelector } from 'react-redux' import { removeFromCart, clearCart, selectCart, addItemToCart, decrementQuantity } from '../../slice/shopSlice' import { Link } from 'react-router-dom' const ItemsInCart = () => { const dispatch = useDispatch(); const cart = useSelector(selectCart) return ( <div className='cart-items-container'> {cart.length === 0 ? <p className='empty-cart-text'>Your cart appears to be empty,<Link to="/" className='home-button'> wanna see the items ?</Link></p> : <> <ul className='cart-items-ul'> {cart.map(i => <li className='cart-item-li' key={i.id}> {i.name} <div className='right-align'> <button onClick={() => dispatch(addItemToCart(i.id))}>+</button> {i.quantity} <button onClick={() => dispatch(decrementQuantity(i.id))}>-</button><button onClick={() => dispatch(removeFromCart(i.id))} className='remove-button'>Remove</button> </div> </li>)} </ul> <button onClick={() => dispatch(clearCart())} className='clear-cart-button'>Clear Cart</button> </> } </div> ) } export default ItemsInCart

Kodun oldukça açıklayıcı olguğunu düşünüyorum, bu yüzden herhangi bir yorum eklemedim. Tam olarak anlamadığınız bir kısım olduğunu düşünüyorsanız, sadece kodu değiştirin ve kendinizinkini yazın, kodla biraz oynayın. Kodu kendinize yüksek sesle açıklayana kadar. Bu, gerçekten bir şey öğrenip öğrenmediğimi anlamaya çalışırken sıklıkla kullandığım bir yöntem.

Artık tüm mantığı da oluşturduğumuza göre, biraz css ekleyebiliriz. Bu bileşen için yazdığım css kodu:

.cart-items-container { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: center; max-width: 960px; min-height: 600px; margin: -40px auto 260px; background: rgb(221, 254, 255); box-shadow: 2px 2px 32px 2px rgb(0, 0, 0); padding: 40px; border-radius: 10px; } .empty-cart-text { font-size: 1.4rem; color: rgb(0, 0, 0); } .home-button { text-decoration: none; color: rgb(121, 121, 255); } .cart-items-ul { color: rgb(0, 0, 0); list-style: none; width: 100%; } .cart-item-li { font-size: 1.4rem; text-transform: capitalize; border-bottom: 1px solid rgb(0, 0, 0); padding: 20px; width: 100%; display: flex; justify-content: space-between; align-items: center; } .right-align > button { padding: 10px 20px; min-width: 70px; margin: 0 20px; border-radius: 5px; font-size: 1.9rem; } .right-align > button:hover { cursor: pointer; } .remove-button { background-color: red; border: 2px solid white; } .clear-cart-button { padding: 10px 20px; min-width: 70px; margin: 0 20px; font-size: 1.9rem; margin-top: 60px; } .clear-cart-button:hover { cursor: pointer; }

Bu kolaydı, değil mi? Ve şimdi Cart.jsx dosyamız şöyle:

import React from 'react' import Banner from '../components/banner/Banner' import ItemsInCart from '../components/inCart/InCart' const Cart = () => { return (<> <Banner text="Cart"/> <ItemsInCart /> </>) } export default Cart

§Sonuç

Şimdi önümüzde bitmiş bir uygulama var. State'i korumak ve değiştirmek için bir "store" kullandık. Durum (State) değişiklikleriyle nasıl başa çıkacağınızı ve prop'u diğer bileşenlere nasıl aktarabileceğinizi bir düşünün Çok sinir bozucu!

Umarım bu projeyi okumaktan, oluşturmaktan keyif almışsınızdır, bu yazıdan da bir şeyler öğrenmişsinizdir ve bunları yaparken eğlenmişsinizdir. Benim için bu metni oluşturmak kesinlikle çok eğlenceliydi.

Burada bırakmayın, bir ödeme işlevi ekleyin, kendi ürünlerinizi oluşturun, bir arka uç (back-end) oluşturun, bir veritabanına bağlanın vb.Kendiniz birşeyler ekleyin ve kesinlike öğrenmeye devam edin!

Ilker Akbiyik