roadmap.az

Menyu

ReactDərs 14 / 15

Redux

Ortaq vəziyyətin axını

Uzaq komponentlər eyni məlumatı paylaşanda əvvəl state-i ortaq valideynə qaldırmağı düşün. Daha mürəkkəb ortaq axında Redux store vəziyyəti saxlayır. Komponent action dispatch edir, reducer növbəti vəziyyəti hesablayır, selector lazımi hissəni oxuyur.

import { configureStore, createSlice } from '@reduxjs/toolkit';
import { Provider, useDispatch, useSelector } from 'react-redux';
const cart = createSlice({
  name: 'cart', initialState: { items: [] },
  reducers: {
    added(state, action) { state.items.push(action.payload); },
    removed(state, action) {
      state.items = state.items.filter(item => item.id !== action.payload);
    }
  }
});
const store = configureStore({ reducer: { cart: cart.reducer } });
function Basket() {
  const items = useSelector(state => state.cart.items);
  const dispatch = useDispatch();
  const total = items.reduce((sum, item) => sum + item.price, 0);
  return <section><p>Cəm: {total} AZN</p>
    <button type="button" onClick={() => dispatch(cart.actions.added({
      id: crypto.randomUUID(), title: 'Çanta', price: 25
    }))}>Məhsul əlavə et</button>
    <ul>{items.map(item => <li key={item.id}>{item.title}
      <button type="button" onClick={() => dispatch(cart.actions.removed(item.id))}>Sil</button>
    </li>)}</ul>
  </section>;
}
export default function App() { return <Provider store={store}><Basket /></Provider>; }
Nümunə

Müasir və klassik API-lər

Redux Toolkit-də createSlice Immer vasitəsilə mutasiya kimi görünən koddan dəyişməz yeniləmə hazırlayır. Adi reducer-də və React state-də bu icazə yoxdur. Klassik kodda createStore, connect, mapStateToProps və mapDispatchToProps ilə rastlaşa bilərsən; yeni Redux kodu üçün Toolkit və Hook-larla başla.

Formanın müvəqqəti input dəyəri yerli state-də qala bilər: Redux hər şeyi store-a daşımaq tələbi deyil. Asinxron məntiq reducer-in içində yox, məsələn thunk kimi middleware axınında işlədilir. configureStore standart olaraq thunk dəstəyi verir; thunk dispatch və getState qəbul edib işi əlaqələndirə bilir.

Əlavə qeydlər və mənbələr

Ortaq state-ə bir neçə uzaq komponent ehtiyac duyduqda store məlumat axınını mərkəzləşdirə bilər. Action baş verəni bildirir, reducer növbəti state-i hesablayır, selector isə lazım olan hissəni oxuyur.

Niyə vacibdir?

Komponentlər və state mürəkkəb interfeysin hissələrini idarə etməyə kömək edir.

Əvvəlki biliklər

Bu mövzuda

  • Store, action, reducer və dispatch
  • Provider və selector
  • Redux Toolkit və React-Redux Hook-ları

Mövzuya baxış

Mənbələr

Məşqin idarəetməsi
Addım 1 / 2

Dəyişiklik axınını izlə

Action-dan yeni store vəziyyətinə gedən yolu tamamla.

Prosesi son vəziyyətə çatdır.

  1. Action hazırdır
  2. Dispatch
  3. Reducer
  4. Görünüş yeniləndi
Action hazırdır

İstifadəçi səbətə məhsul əlavə edir.

{ type: "cart/added", payload: product }

Bu məşq prosesi modelləşdirir.

Özün sına

Məhsul siyahısı və səbət üçün ortaq store yarat. Məhsul əlavə etmə, say dəyişmə və silmə davranışlarını qur; ümumi məbləği məlumatdan hesabla.

Nəticəni necə yoxlayım?

Provider ilə birləşdirilmiş komponentlər eyni səbəti oxuyur; dispatch yeniləyir və ümumi məbləğ selector ilə hesablanır.

Gözlənilən nəticə

  • İki Kitab və bir Çanta əlavə ediləndə cəmi 49 AZN olur.
  • Say dəyişdirildikdə məbləğ yenidən hesablanır; silmə məhsulu səbətdən çıxarır.
Görünüş nümunəsi

Bu, görünüş nümunəsidir. İnteraktiv davranışı kodu öz layihəndə işlədərək yoxla.

Nümunə həllə bax

Əvvəl özün sına, sonra müqayisə et. Bu, mümkün həllərdən biridir.

Ortaq store-da məhsullar və səbət saxlanılır. createSlice daxilində dəyişən sintaksisini Immer təhlükəsiz yeni state-ə çevirir; məbləğ ayrıca saxlanmır.

App.jsx

import { configureStore, createSlice } from '@reduxjs/toolkit';
import { Provider, useDispatch, useSelector } from 'react-redux';
const slice = createSlice({ name: 'shop', initialState: {
  products: [{ id: 1, title: 'Kitab', price: 12 }, { id: 2, title: 'Çanta', price: 25 }], cart: []
}, reducers: {
  add(state, action) {
    const line = state.cart.find(item => item.id === action.payload);
    if (line) line.quantity += 1; else state.cart.push({ id: action.payload, quantity: 1 });
  },
  quantity(state, action) {
    const line = state.cart.find(item => item.id === action.payload.id);
    if (line && Number.isInteger(action.payload.quantity) && action.payload.quantity >= 1) line.quantity = action.payload.quantity;
  },
  remove(state, action) { state.cart = state.cart.filter(item => item.id !== action.payload); }
} });
const store = configureStore({ reducer: { shop: slice.reducer } });
function Shop() {
  const { products, cart } = useSelector(state => state.shop);
  const dispatch = useDispatch();
  const total = cart.reduce((sum, line) => sum + products.find(product => product.id === line.id).price * line.quantity, 0);
  return <><h1>Məhsullar</h1>{products.map(product => <p key={product.id}>{product.title} — {product.price} AZN <button onClick={() => dispatch(slice.actions.add(product.id))}>Əlavə et</button></p>)}
    <h2>Səbət</h2>{cart.map(line => <p key={line.id}>{products.find(product => product.id === line.id).title}
      <label> Say <input type="number" min="1" value={line.quantity} onChange={event => dispatch(slice.actions.quantity({ id: line.id, quantity: Number(event.target.value) }))} /></label>
      <button onClick={() => dispatch(slice.actions.remove(line.id))}>Sil</button></p>)}<p>Cəmi: {total} AZN</p></>;
}
export default function App() { return <Provider store={store}><Shop /></Provider>; }

qurasdirma.txt

React təlim layihəsində: npm install @reduxjs/toolkit react-redux

Praktikanı bitirdin?Özün qiymətləndirirsən. İrəliləyiş bu brauzerdə saxlanılır.