React Context API ile Çalışmak

Yayınlanan: 2022-03-11

React Context API, bir süredir deneysel bir özellik olarak kullanılıyor, ancak yalnızca React'in 16.3.0 sürümünde üretimde kullanımı güvenli hale geldi. Aşağıdaki makale, biri Context API ile oluşturulmuş ve diğeri onsuz olmak üzere iki temel web mağazası uygulamasını gösterecektir.

Bu yeni API, önemli bir sorunu çözüyor: pervane sondajı . Terime aşina olmasanız bile, bir React.js uygulaması üzerinde çalıştıysanız, muhtemelen başınıza gelmiştir. Prop sondajı, birden çok ara React bileşeni katmanından geçirilerek A bileşeninden Z bileşenine veri alma işlemidir. Bileşen dolaylı olarak destek alacak ve siz , React Developer olarak her şeyin yolunda gittiğinden emin olmanız gerekecek.

React Context API'si olmadan genel sorunları nasıl çözeceğinizi keşfedelim,

App.js

 class App extends Component { state = { cars: { car001: { name: 'Honda', price: 100 }, car002: { name: 'BMW', price: 150 }, car003: { name: 'Mercedes', price: 200 } } }; incrementCarPrice = this.incrementCarPrice.bind(this); decrementCarPrice = this.decrementCarPrice.bind(this); incrementCarPrice(selectedID) { // a simple method that manipulates the state const cars = Object.assign({}, this.state.cars); cars[selectedID].price = cars[selectedID].price + 1; this.setState({ cars }); } decrementCarPrice(selectedID) { // a simple method that manipulates the state const cars = Object.assign({}, this.state.cars); cars[selectedID].price = cars[selectedID].price - 1; this.setState({ cars }); } render() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1 className="App-title">Welcome to my web store</h1> </header> {/* Pass props twice */} <ProductList cars={this.state.cars} incrementCarPrice={this.incrementCarPrice} decrementCarPrice={this.decrementCarPrice} /> </div> ); } }

Ürün Listesi .js

 const ProductList = props => ( <div className="product-list"> <h2>Product list:</h2> {/* Pass props twice */} <Cars cars={props.cars} incrementCarPrice={props.incrementCarPrice} decrementCarPrice={props.decrementCarPrice} /> {/* Other potential product categories which we will skip for this demo: */} {/* <Electronics /> */} {/* <Clothes /> */} {/* <Shoes /> */} </div> ); export default ProductList;

arabalar.js

 const Cars = props => ( <Fragment> <h4>Cars:</h4> {/* Finally we can use data */} {Object.keys(props.cars).map(carID => ( <Car key={carID} name={props.cars[carID].name} price={props.cars[carID].price} incrementPrice={() => props.incrementCarPrice(carID)} decrementPrice={() => props.decrementCarPrice(carID)} /> ))} </Fragment> );

araba.js

 const Cars = props => ( <Fragment> <p>Name: {props.name}</p> <p>Price: ${props.price}</p> <button onClick={props.incrementPrice}>&uarr;</button> <button onClick={props.decrementPrice}>&darr;</button> </Fragment> );

Elbette bu, verilerinizi işlemenin en iyi yolu değil, ancak umarım pervane delmenin neden berbat olduğunu gösterir. Peki Context API bundan kaçınmamıza nasıl yardımcı olabilir?

Bağlam Web Mağazasına Giriş

Uygulamayı yeniden gözden geçirelim ve neler yapabileceğini gösterelim. Birkaç kelimeyle, Context API, verilerinizin bulunduğu merkezi bir depoya sahip olmanızı sağlar (evet, tıpkı Redux'ta olduğu gibi). Mağaza doğrudan herhangi bir bileşene eklenebilir. Aracıyı kesebilirsin!

İki durum akışı örneği: biri React Context API'li ve diğeri

Yeniden düzenleme oldukça kolaydır; bileşenlerin nasıl yapılandırıldığı konusunda herhangi bir değişiklik yapmamıza gerek yoktur. Bununla birlikte, bir sağlayıcı ve bir tüketici olmak üzere bazı yeni bileşenler yaratmamız gerekiyor.

1. Bağlamı Başlatın

İlk olarak, daha sonra sağlayıcılar ve tüketiciler oluşturmak için kullanabileceğimiz bağlamı yaratmamız gerekiyor.

MyContext.js

 import React from 'react'; // this is the equivalent to the createStore method of Redux // https://redux.js.org/api/createstore const MyContext = React.createContext(); export default MyContext;

2. Sağlayıcıyı Oluşturun

Bu yapıldıktan sonra, bağlamı içe aktarabilir ve MyProvider olarak adlandırdığımız sağlayıcımızı oluşturmak için kullanabiliriz. İçinde, sağlayıcı bileşenimiz olan value prop aracılığıyla paylaşabileceğiniz bazı değerlere sahip bir durum başlatıyoruz. Örneğimizde, durumu manipüle eden birkaç yöntemle this.state.cars paylaşıyoruz. Bu yöntemleri Redux'daki redüktörler olarak düşünün.

Sağlayıcım.js

 import MyContext from './MyContext'; class MyProvider extends Component { state = { cars: { car001: { name: 'Honda', price: 100 }, car002: { name: 'BMW', price: 150 }, car003: { name: 'Mercedes', price: 200 } } }; render() { return ( <MyContext.Provider value={{ cars: this.state.cars, incrementPrice: selectedID => { const cars = Object.assign({}, this.state.cars); cars[selectedID].price = cars[selectedID].price + 1; this.setState({ cars }); }, decrementPrice: selectedID => { const cars = Object.assign({}, this.state.cars); cars[selectedID].price = cars[selectedID].price - 1; this.setState({ cars }); } }} > {this.props.children} </MyContext.Provider> ); } }

Sağlayıcıyı diğer bileşenlere erişilebilir kılmak için uygulamamızı onunla sarmamız gerekiyor (evet, tıpkı Redux'ta olduğu gibi). Hazır buradayken, durum ve yöntemlerden kurtulabiliriz çünkü bunlar artık MyProvider.js'de tanımlanmıştır.

App.js

 class App extends Component { render() { return ( <MyProvider> <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1 className="App-title">Welcome to my web store</h1> </header> <ProductList /> </div> </MyProvider> ); } }

3. Tüketiciyi Yarat

Bağlamı tekrar içe aktarmamız ve bileşene bağlam argümanını enjekte eden bileşenimizi onunla sarmamız gerekecek. Daha sonra, oldukça düz ileri. Props kullandığınız gibi bağlamı kullanırsınız. MyProducer'da paylaştığımız tüm değerleri barındırıyor, sadece onu kullanmamız gerekiyor!

arabalar.js

 const Cars = () => ( <MyContext.Consumer> {context => ( <Fragment> <h4>Cars:</h4> {Object.keys(context.cars).map(carID => ( <Car key={carID} name={context.cars[carID].name} price={context.cars[carID].price} incrementPrice={() => context.incrementPrice(carID)} decrementPrice={() => context.decrementPrice(carID)} /> ))} </Fragment> )} </MyContext.Consumer> );

Ne unuttuk? Ürün Listesi! İşte bu noktada fayda ortaya çıkıyor. Herhangi bir veri veya yöntem iletmiyoruz. Bileşen basitleştirilmiştir, çünkü yalnızca birkaç bileşeni işlemesi gerekir.

Ürün Listesi.js

 const ProductList = () => ( <div className="product-list"> <h2>Product list:</h2> <Cars /> {/* Other potential product categories which we will skip for this demo: */} {/* <Electronics /> */} {/* <Clothes /> */} {/* <Shoes /> */} </div> );

Bu makale boyunca Redux ve Context API arasında birkaç karşılaştırma yaptım. Redux'un en büyük avantajlarından biri, uygulamanızın herhangi bir bileşenden erişilebilen bir merkezi mağazaya sahip olabilmesidir. Yeni Context API ile varsayılan olarak bu işlevselliğe sahipsiniz. Context API'nin Redux'u modası geçmiş hale getireceği konusunda pek çok hype yapıldı.

Bu, Redux'u yalnızca merkezi mağaza yetenekleri için kullananlarınız için doğru olabilir. Kullanmakta olduğunuz tek özellik buysa, artık bunu Context API ile değiştirebilir ve üçüncü taraf kitaplıkları kullanmadan pervane sondajından kaçınabilirsiniz.

React uygulamanızın performansını ölçmek ve optimize etmekle ilgileniyorsanız, Toptaler William Wang'ın yazdığı React Performansını Optimize Etme Kılavuzu'nu okuyun.