React'e Giriş, bölüm 3
Geçen hafta, bir React bileşeninin, uygulama durumumuzun (bir parçasının) grafiksel gösteriminden başka bir şey olmadığını gördük. Uyguladığımız örnekte, bir bileşen, söz konusu değeri artırmaya veya azaltmaya izin veren iki düğme ile birlikte bir sayacın değerini gösterdi. İşin püf noktası basitti: Bir bileşenin props hem veri hem de işlev olabilir.
Şimdiye kadar, bu öğreticinin 1. ve 2. bölümlerinden öğrendiğimiz iki ana fikir şunlardır:
- Bir React bileşeni, bir dizi özelliği alan ve onu oluşturmak için gereken HTML'yi oluşturan saf bir işlevdir .
- Bir React bileşeninin aldığı özellikler (a) kullanıcı arayüzünde göstermesi gereken veriler ve (b) DOM olaylarına geri çağrılar olarak bağlandıktan sonra uygulamamızın durumunu değiştiren işlevler olabilir.
Bu üçüncü bölümde, bu mimari hakkındaki bilgimizi biraz daha genişleteceğiz ve WordPress mağazalarını nasıl kullanacağımızı öğreneceğiz. Onlarla, uygulamamızın durumunu temiz, test edilebilir ve kullanıcı arayüzünden bağımsız bir şekilde tanımlayabiliriz.
Örneğimizi Genişletme
Bu öğreticinin ikinci bölümünde, değerini artırmak veya azaltmak için birkaç düğmeli bir sayaç oluşturduk. Bunu yapmak için, index.js dosyasına onu mutasyona uğratacak bir fonksiyonla birlikte değişken bir değişken ekledik. Sayaç bileşenimiz:
export const Counter = ( { value, onIncrease, onDecrease } ) => ( <div> <div>Counter: <strong>{ value }</strong></div> <button onClick={ onIncrease }>+</button> <button onClick={ onDecrease }>-</button> </div> );
daha sonra ihtiyaç duyduğu tüm sahne malzemelerini alabilirdi:
// Import dependencies import { render } from '@wordpress/element'; import { Counter } from './components/counter'; // Store value let value = 0; function setValue( newValue ) { value = newValue; } // Render component in DOM const wrapper = document.getElementById( 'react-example-wrapper' ); render( <Counter value={ value } onIncrease={ () => setValue( value + 1 ) } onDecrease={ () => setValue( value - 1 ) } />, wrapper );
Eh, bugün devlet yönetimini nasıl düzgün ve daha iyi uygulayabileceğimizi öğreneceğiz. Ama önce, daha karmaşık bir örneği hedeflememe izin verin: uygulamamızı aynı anda birden fazla sayacı olacak şekilde genişletelim ve bir WordPress mağazası kullanarak hepsini nasıl yönetebileceğimizi görelim. Nihai sonuç (bir sonraki gönderide uygulayacağımız) şuna benzer:

Uygulamamızın Durumunun Tanımlanması
Böyle bir sorunla karşılaştığınızda düşünmeniz gereken ilk şey uygulamanızın durumunu nasıl yöneteceğinizdir. Ve yalnızca işlevleri kullanarak durumu okuyup yazabileceğinizi varsayarsak, bunu yapmanın en kolay yolu API'sini düşünmektir: yani, onu sorgulamanıza ve güncellemenize izin veren işlevler . Bizim durumumuzda şunu önerebilirim:
- Yeni bir sayaç ekleme
- Sayaç x siliniyor
- Sayacın değerini ayarlayın x
- Uygulamamızın sahip olduğu tüm sayaçların bir listesini alın
- x sayacının değerini alın
ancak farklı bir yaklaşım kullanmak isteyebilirsiniz (örneğin, belirli bir sayacı artırmak için bir işlev ve onu azaltmak için farklı bir işlev oluşturmak isteyebilirsiniz).
Bu arayüzü tanımladıktan sonra , bu durumu takip etmek için ihtiyaç duyduğunuz bilgileri ve özellikle bunu yapmak için kullanacağınız veri yapısını düşünmelisiniz. Örneğimizde, birkaç sayacı takip etmek istiyoruz ve her x sayacı için değerini bilmek istiyoruz. Hangi veri yapıları bu çabada bize yardımcı olabilir?
Bu x'in ne olduğuna bağlı olarak, bir veri yapısını veya diğerini kullanmak isteyebilirsiniz. Örneğin, x sayacın diziniyse (yani, birinci , ikinci veya üçüncü sayacın değerini alabilmek istiyorsanız), bir dizi sayı yeterli olabilir. x'in benzersiz bir sayaç tanımlayıcısı olmasını istiyorsanız, farklı bir yaklaşım kullanmak isteyebilirsiniz. Örneğin, kimlik/değer çiftleri içeren bir sözlük kullanmak isteyebilirsiniz:
const counters = { ae13a: 0, f18bb: 3, e889a: 1, 8b1d3: -5, };
veya bir dizi nesne:
const counters = [ { id: 'ae13a', value: 0 }, { id: 'f18bb', value: 3 }, { id: 'e889a', value: 1 }, { id: '8b1d3', value: -5 }, ];
İlk önce uygulamanızın durumunu değiştirmek ve erişmek için arabirimi (eğer yapacaksanız ayarlayıcılar ve alıcılar) tanımlarsanız, durumu nasıl uyguladığınız bir kara kutudur. Bu, mağazanın kendisini istediğiniz zaman değiştirebileceğiniz ve API'yi koruduğunuz sürece her şeyin beklendiği gibi çalışacağı anlamına gelir.
WordPress ile Redux Tabanlı Mağaza Oluşturma
WordPress' veri modülü, uygulamanızın durumunu yönetmek için bir veya daha fazla mağaza tanımlamanıza olanak tanır. Bu paketi kullanarak yeni bir mağaza oluşturmak için, aşağıdaki argümanlarla registerStore işlevini kullanmanız yeterlidir:
- Mağazanızı benzersiz şekilde tanımlayan bir ad
- Mağazadan veri almak için tüm alıcılara sahip bir
selectorsnesnesi - Güncelleme isteklerini tetikleyen işlevli bir
actionsnesnesi (bunun ne anlama geldiği hakkında daha sonra bu gönderide konuşacağız) - Belirli eylemler tetiklendiğinde durumu güncellemekten sorumlu olan bir
reducerişlevi
Gerçek bir örnek görelim, olur mu? Geçen haftaki örnekle devam ederek, src içinde yeni bir store klasörü oluşturun. Ardından, içinde aşağıdaki kodla bir index.js dosyası oluşturun:
// Load dependencies import { registerStore } from '@wordpress/data'; import reducer from './reducer'; import * as actions from './actions'; import * as selectors from './selectors'; registerStore( 'react-example/counters', { actions, reducer, selectors, } );
Snippet oldukça basit, değil mi? Sadece bahsettiğimiz registerStore işlevini ve henüz oluşturmadığımız birkaç bağımlılığı ( reducer , actions ve selectors ) içe aktarır ve yeni mağazayı kaydeder. Benzersiz olduğundan emin olmak için mağazamızı nasıl adlandırdığımıza dikkat edin: Eklentimizin adını ( react-example ) mağazanın ne hakkında olduğunu tanımlayan bir sözcükle ( counters ) birleştirdik. Tereyağından kıl çeker gibi!
Mağazadaki Eylemler
Her mağazanın (prensipte) ihtiyaç duyduğu şeylerden biri, durumunu değiştirmemize izin veren bir dizi işlevdir. Örneğimizde, eylemler src/store/actions.js içinde olacaktır:
export function addCounter( counterId ) { return { type: 'ADD_COUNTER', counterId, }; } export function removeCounter( counterId ) { return { type: 'REMOVE_COUNTER', counterId, }; } export function setCounterValue( counterId, value ) { return { type: 'SET_COUNTER_VALUE', counterId, value, }; }
Beklendiği gibi, mağazamızın durumunu güncellemek için üç eylemi vardır:
-
addCounter: mağazamıza yeni sayaçlar ekleyen bir fonksiyon. Aldığı tek argüman yeni sayacın kimliğidir. -
removeCounter: mevcut bir sayacı kaldıran bir işlev. Yine, alacağı tek argüman, kaldırmak istediğimiz sayacın kimliğidir. -
setCounterValue: belirli bir sayaca yeni bir değer ayarlayan bir işlev. Açıkçası, bu işlev iki argüman alır: güncellenecek sayacın kimliği ve yeni değeri.
Şimdi, her bir eyleme yakından bakarsanız şaşırabilirsiniz: Bu eylemlerin hiçbiri hiçbir şeyi güncellemiyor gibi görünüyor. Bunun yerine nesneleri döndürürler. Burada neler oluyor?
Redux'ta (ve WordPress mağazaları Redux'u temel alır), eylemler bir mağazayı doğrudan değiştirmez. Bunun yerine, bir "güncelleme isteği" sinyalini veren bir nesne üretirler. Bu istekler her zaman aynı kalıbı takip eder: bunlar, isteği benzersiz bir şekilde tanımlayan type özniteliğine ve istenen güncellemeyi başarıyla uygulamak için gerektiği kadar ek özelliğe sahip bir nesnedir.
Şimdi bir kişinin durumu nasıl güncelleyebileceğini görelim…
Bir Mağazanın Durumunu Güncellemek için Düşürücüyü Uygulamak
Mağaza eylemleri yalnızca bir güncelleme isteğini temsil ediyorsa, böyle bir istek gönderildiğinde mağazamızın durumunu gerçekten güncelleyecek birine veya bir şeye ihtiyacımız var. Redüktör bunun için kullanılır.
İndirgeyici, uygulamamızın mevcut durumunu ve birisinin gönderdiği bir eylemi alan ve istenen güncellemeyi uygulayarak durumu güncelleyen bir işlevdir .
Önceki bölümde mağazamızın üç eylemi olduğunu gördük, bu nedenle redüktörümüz her birini uygulayabilmelidir:
import { omit } from 'lodash'; export default function reducer( state = {}, action ) { switch ( action.type ) { case 'ADD_COUNTER': return { ...state, [ action.counterId ]: 0, }; case 'REMOVE_COUNTER': return omit( state, action.counterId ); case 'SET_COUNTER_VALUE': return { ...state, [ action.counterId ]: action.value, }; } return state; }
Gördüğünüz gibi, indirgeyici önceki state (bu arada, varsayılan olarak boş nesne {} ) ve durumu güncellemek için gönderilen eylemi alır. Redüktörün gövdesi oldukça basittir:
- Çalıştırmamız gereken güncelleme türünü (
action.type) ayırt etmek için birswitchifadesi ile başlar:-
ADD_COUNTERise, sayaç değeri0olarak ayarlanmış yeni biraction.counterIdanahtarıyla yeni birstatenesnesi oluşturur. -
REMOVE_COUNTERise,action.counterIdanahtarı olmadan yeni birstatenesnesi oluşturur. -
SET_COUNTER_VALUEise,action.counterIdiçindeki değerin şimdiaction.valueolarak ayarlandığı yeni birstatenesnesi oluşturur.
-
Buradaki en önemli şey, bir redüktörün saf bir fonksiyon olduğunu (ve olması gerektiğini) anlamaktır . Bu, mevcut durumda yaptığımız herhangi bir değişikliğin yeni bir durum oluşturmayı içerdiği anlamına gelir. O halde hiçbir koşulda önceki durumu değiştirmemelisiniz.
Mağazadaki Seçiciler
Artık mağazanızın durumunu nasıl güncelleyeceğinizi bildiğinize göre, öğrenmeniz gereken tek şey onu nasıl sorgulayacağınızdır. İhtiyacınız olan sorgu işlevleriyle bir selectors.js tanımlamanız yeterlidir:
export function getCounterIds( state ) { return Object.keys( state ); } export function getCounterValue( state, counterId ) { return state[ counterId ]; }
ve bu kadar! Oldukça açık, değil mi? Mağaza seçicileri (en az) bir argüman (mağazanın state ) alan ve belirli bir değer döndüren işlevlerdir . Açıkçası, mağazanızdan belirli bir değer döndürmeniz gerekiyorsa, seçicilerin daha fazla argümanı olabilir.
Örneğin bizim durumumuzda iki seçici oluşturduk:
-
getCounterIds, bir dizi sayaç tanımlayıcısı döndürür. Mağazayı bir sözlük/nesne kullanarak uyguladığımız için, yalnızcaObject.keysdöndürmekle ilgileniyoruz. -
getCounterValue, belirli bir sayacın belirli değerini döndürür. Bu işlev iki argüman alır (uygulamamızın mevcutstateve ilgilendiğimiz sayacın kimliği) ve istenen değeri döndürür.
Mağazamızı Test Etme
Mağazanın düzgün çalıştığını test etmek için src/index.js dosyasını açın ve import :
// Import dependencies import { render } from '@wordpress/element'; import './store'; import { Counter } from './components/counter'; ...
Ardından kodu aktarın ( npm run build kullanarak) ve tarayıcınıza gidin. Geliştirici Araçlarını açın ve birkaç komut yazmak için JavaScript konsolunu kullanın:
dispatch = wp.data.dispatch( 'react-example/counters' ); select = wp.data.select( 'react-example/counters' ); dispatch.addCounter( 'a' ); dispatch.addCounter( 'b' ); dispatch.addCounter( 'c' ); dispatch.setCounterValue( 'a', 3 ); select.getCounterIds(); // Array(3) [ "a", "b", "c" ] select.getCounterValue( 'a' ); // 3
WordPress'in dispatch ve select işlevlerini kullanarak, mağazanın beklendiği gibi çalıştığını görebileceksiniz. Ve bonus ipucu: Redux mağazalarınızı düzgün bir şekilde görmenizi sağlayan Redux DevTools adlı hem Firefox hem de Chrome için bir uzantı var:

Sonraki adımlar
Gerçek şu ki, bugünün gönderisi beklediğimden biraz daha uzundu, bu yüzden bu mağazayı UI'mizi güçlendirmek için nasıl kullanabileceğimizi göremeyeceğiz (henüz). Ancak umarım açıklama, WordPress mağazalarının nasıl çalıştığını ve eklentilerinizin durumunu yönetmek için bunları nasıl kullanabileceğinizi anlamanıza yardımcı olur.
Gelecek hafta, bugünün örneğiyle ilerleyeceğiz ve React bileşenlerimizi mağazaya bağlayacağız, böylece (a) kullanıcı arayüzünde gördüğümüz şey mağazada depolanan durum tarafından desteklenir ve (b) kullanıcı arayüzü ile kullanıcı etkileşimleri mağazayı günceller ( yanı sıra kullanıcı arayüzünün kendisi).
Ancak, bugün size gösterdiğim her şeyle kendinizi rahat hissetmenizi sağlamak için, bazı ödevler önermeme izin verin: bugün uyguladığımız mağazayı, veriler aşağıdaki gibi depolanacak şekilde değiştirin:
const counters = [ { id: 'ae13a', value: 0 }, { id: 'f18bb', value: 3 }, { id: 'e889a', value: 1 }, { id: '8b1d3', value: -5 }, ];
ve artık bize bir sözlük değil. Çalışması için seçicileri, eylemleri ve azaltıcıyı güncellemeniz gerekebileceğini unutmayın! Çözümü haftaya paylaşacağım
Annie Theby tarafından Unsplash'ta Öne Çıkan Resim.
ev borcu WordPress sitesi