摘要:翻譯瘋狂的技術(shù)宅原文本文首發(fā)微信公眾號(hào)歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章現(xiàn)在已經(jīng)成為一個(gè)實(shí)驗(yàn)性功能,但是只有在中才能用在生產(chǎn)中。創(chuàng)建完成后,我們可以導(dǎo)入并用它來創(chuàng)建我們的,我們稱之為。在巨大的宣傳攻勢(shì)下將會(huì)使變得過時(shí)。
翻譯:瘋狂的技術(shù)宅
原文:https://www.toptal.com/react/...
本文首發(fā)微信公眾號(hào):jingchengyideng
歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章
React Context API 現(xiàn)在已經(jīng)成為一個(gè)實(shí)驗(yàn)性功能,但是只有在 React 16.3.0 中才能用在生產(chǎn)中。本文將向你展示兩個(gè)基本的 Web 商店應(yīng)用程序,一個(gè)使用了 Context API 進(jìn)行構(gòu)建,另一個(gè)則不用。
這個(gè)新的API解決了一個(gè)嚴(yán)重的問題 ——prop drilling。 即使你不熟悉這個(gè)術(shù)語,如果你曾經(jīng)用 React.js 做過開發(fā),它可能就已經(jīng)在你身上發(fā)生過了。 Prop drilling 是通過將數(shù)據(jù)傳遞到多個(gè)中間 React 組件層,將數(shù)據(jù)從組件A 獲取到組件 Z 的過程。 組件將間接的接收props,而你必須確保一切正常。
我們先探討如何在沒有 React Context API 的情況下處理常見問題:
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 (); } }{/* Pass props twice */} Welcome to my web store
ProductList .js
const ProductList = props => (); export default ProductList;Product list:
{/* Pass props twice */}{/* Other potential product categories which we will skip for this demo: */} {/* */} {/* */} {/* */}
Cars.js
const Cars = props => (); Cars:
{/* Finally we can use data */} {Object.keys(props.cars).map(carID => (props.incrementCarPrice(carID)} decrementPrice={() => props.decrementCarPrice(carID)} /> ))}
Car.js
const Cars = props => (); Name: {props.name}
Price: ${props.price}
當(dāng)然,這不是處理數(shù)據(jù)的最好方式,但我希望能夠用它說明為什么 prop drilling 很差勁。 那么 Context API 是如何幫我們避免這種情況呢?
介紹Context Web Store讓我們重構(gòu)程序并演示它可以做些什么。 簡而言之,Context API 允許你擁有一個(gè)存儲(chǔ)數(shù)據(jù)的中央存儲(chǔ)(是的,就像存儲(chǔ)在 Redux 中一樣)。你可以把任何組件直接插入到商店應(yīng)用中,也可以切斷 middleman!
重構(gòu)非常簡單 —— 我們不必對(duì)組件的結(jié)構(gòu)進(jìn)行任何修改。但是我們確實(shí)需要?jiǎng)?chuàng)建一些新組件:Provider 和 consumer。
1.初始化 Context首先,我們需要?jiǎng)?chuàng)建context,后面可以使用它來創(chuàng)建 Provider 和 consumer。
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. 創(chuàng)建 Provider
完成后,我們可以導(dǎo)入 context 并用它來創(chuàng)建我們的 provider,我們稱之為 MyProvider。在里面使用一些值初始化一個(gè)狀態(tài),你可以通過 value prop 共享我們的 provider 組件。 在例子中,我們將共享 this.state.cars 以及一些操縱狀態(tài)的方法。 將這些方法可以看作是 Redux 中的 Reducer。
MyProvider.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 ({ 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} ); } }
為了使 provider 可以訪問其他組件,我們需要用它包裝我們的應(yīng)用程序(沒錯(cuò),就像 Redux 一樣)。我們可以擺脫這些狀態(tài)和方法,因?yàn)樗鼈冊(cè)?MyProvider.js 中定義。
App.js
class App extends Component { render() { return (3. 創(chuàng)建 Consumer); } } Welcome to my web store
我們需要再次導(dǎo)入 context 并用它包裝我們的組件,它會(huì)在組件中注入context 參數(shù)。 之后,它非常直接。 你使用 context 就像用 props 一樣。 它包含我們?cè)?MyProducer 中共享的所有值,我們所需要做的只是去使用它!
Cars.js
const Cars = () => ({context => ( );)} Cars:
{Object.keys(context.cars).map(carID => (context.incrementPrice(carID)} decrementPrice={() => context.decrementPrice(carID)} /> ))}
我們似乎忘記了什么?是 ProductList !它使好處變得非常明顯。 我們不必傳遞任何數(shù)據(jù)或方法。這個(gè)組件被簡化,因?yàn)樗恍枰ヤ秩疽恍┙M件。
ProductList.js
const ProductList = () => ();Product list:
{/* Other potential product categories which we will skip for this demo: */} {/* */} {/* */} {/* */}
在本文中,我對(duì) Redux 和 Context API 進(jìn)行了一些比較。 Redux 最大的優(yōu)勢(shì)之一就是你的應(yīng)用可以擁有一個(gè)可以從任何組件訪問的中央存儲(chǔ)。而使用新的 Context API,默認(rèn)情況下你已經(jīng)有了這個(gè)功能。 在巨大的宣傳攻勢(shì)下 Context API 將會(huì)使 Redux 變得過時(shí)。
對(duì)于那些只把 Redux 作為中央存儲(chǔ)功能的人來說,可能確實(shí)如此。 如果你只使用 Redux 的這一個(gè)功能,現(xiàn)在可以使用 Context API 替換它,并避免在不使用第三方庫的情況下進(jìn)行 prop drilling。
本文首發(fā)微信公眾號(hào):jingchengyideng
歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/101893.html
摘要:希望大家在這浮夸的前端圈里,保持冷靜,堅(jiān)持每天花分鐘來學(xué)習(xí)與思考。 今天的React題沒有太多的故事…… 半個(gè)月前出了248個(gè)Vue的知識(shí)點(diǎn),受到很多朋友的關(guān)注,都強(qiáng)烈要求再出多些React相前的面試題,受到大家的邀請(qǐng),我又找了20多個(gè)React的使用者,他們給出了328道React的面試題,由我整理好發(fā)給大家,同時(shí)發(fā)布在了前端面試每日3+1的React專題,希望對(duì)大家有所幫助,同時(shí)大...
摘要:怎樣使用假設(shè)有個(gè)如下的結(jié)構(gòu)上面的例子中,我們把手動(dòng)的方式傳給了,這期間穿越了,而對(duì)本身沒有什么用。不建議使用絕大多數(shù)的應(yīng)用程序是不需要使用的。如果項(xiàng)目對(duì)數(shù)據(jù)管理較為復(fù)雜,推薦使用類似于或這樣的狀態(tài)管理庫,而不要使用。 What is Context 今天在學(xué)習(xí)styled-components的Theming時(shí),關(guān)于styled-components對(duì)主題的實(shí)現(xiàn)與管理上提到,主要應(yīng)用到...
摘要:但是,有一件事是肯定的年對(duì)全棧開發(fā)者的需求量很大。有一些方法可以解決這個(gè)問題,例如模式,或者你可以這么想,其實(shí)谷歌機(jī)器人在抓取單頁應(yīng)用程序時(shí)沒有那么糟糕。谷歌正在這方面努力推進(jìn),但不要指望在年會(huì)看到任何突破。 對(duì)于什么是全棧開發(fā)者并沒有一個(gè)明確的定義。但是,有一件事是肯定的:2019 年對(duì)全棧開發(fā)者的需求量很大。在本文中,我將向你概述一些趨勢(shì),你可以嘗試根據(jù)這些趨勢(shì)來確定你可能要投入的...
摘要:但是,有一件事是肯定的年對(duì)全棧開發(fā)者的需求量很大。有一些方法可以解決這個(gè)問題,例如模式,或者你可以這么想,其實(shí)谷歌機(jī)器人在抓取單頁應(yīng)用程序時(shí)沒有那么糟糕。谷歌正在這方面努力推進(jìn),但不要指望在年會(huì)看到任何突破。 對(duì)于什么是全棧開發(fā)者并沒有一個(gè)明確的定義。但是,有一件事是肯定的:2019 年對(duì)全棧開發(fā)者的需求量很大。在本文中,我將向你概述一些趨勢(shì),你可以嘗試根據(jù)這些趨勢(shì)來確定你可能要投入的...
摘要:但是,有一件事是肯定的年對(duì)全棧開發(fā)者的需求量很大。有一些方法可以解決這個(gè)問題,例如模式,或者你可以這么想,其實(shí)谷歌機(jī)器人在抓取單頁應(yīng)用程序時(shí)沒有那么糟糕。谷歌正在這方面努力推進(jìn),但不要指望在年會(huì)看到任何突破。 對(duì)于什么是全棧開發(fā)者并沒有一個(gè)明確的定義。但是,有一件事是肯定的:2019 年對(duì)全棧開發(fā)者的需求量很大。在本文中,我將向你概述一些趨勢(shì),你可以嘗試根據(jù)這些趨勢(shì)來確定你可能要投入的...
閱讀 1454·2019-08-30 12:54
閱讀 1936·2019-08-30 11:16
閱讀 1669·2019-08-30 10:50
閱讀 2549·2019-08-29 16:17
閱讀 1344·2019-08-26 12:17
閱讀 1435·2019-08-26 10:15
閱讀 2451·2019-08-23 18:38
閱讀 842·2019-08-23 17:50