资讯专栏INFORMATION COLUMN

怎样使用React Context API

anRui / 1784人阅读

摘要:翻译疯狂的技术宅原文本文首发微信公众号欢迎关注,每天都给你推送新鲜的前端技术文章现在已经成为一个实验性功能,但是只有在中才能用在生产中。创建完成后,我们可以导入并用它来创建我们的,我们称之为。在巨大的宣传攻势下将会使变得过时。

翻译:疯狂的技术宅
原文:https://www.toptal.com/react/...

本文首发微信公众号:jingchengyideng
欢迎关注,每天都给你推送新鲜的前端技术文章

React Context API 现在已经成为一个实验性功能,但是只有在 React 16.3.0 中才能用在生产中。本文将向你展示两个基本的 Web 商店应用程序,一个使用了 Context API 进行构建,另一个则不用。

这个新的API解决了一个严重的问题 ——prop drilling。 即使你不熟悉这个术语,如果你曾经用 React.js 做过开发,它可能就已经在你身上发生过了。 Prop drilling 是通过将数据传递到多个中间 React 组件层,将数据从组件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 (
            

Welcome to my web store

{/* Pass props twice */}
); } }

ProductList .js

const ProductList = props => (
    

Product list:

{/* Pass props twice */} {/* Other potential product categories which we will skip for this demo: */} {/* */} {/* */} {/* */}
); export default ProductList;

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}

);

当然,这不是处理数据的最好方式,但我希望能够用它说明为什么 prop drilling 很差劲。 那么 Context API 是如何帮我们避免这种情况呢?

介绍Context Web Store

让我们重构程序并演示它可以做些什么。 简而言之,Context API 允许你拥有一个存储数据的中央存储(是的,就像存储在 Redux 中一样)。你可以把任何组件直接插入到商店应用中,也可以切断 middleman!

重构非常简单 —— 我们不必对组件的结构进行任何修改。但是我们确实需要创建一些新组件:Provider 和 consumer。

1.初始化 Context

首先,我们需要创建context,后面可以使用它来创建 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. 创建 Provider

完成后,我们可以导入 context 并用它来创建我们的 provider,我们称之为 MyProvider。在里面使用一些值初始化一个状态,你可以通过 value prop 共享我们的 provider 组件。 在例子中,我们将共享 this.state.cars 以及一些操纵状态的方法。 将这些方法可以看作是 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 可以访问其他组件,我们需要用它包装我们的应用程序(没错,就像 Redux 一样)。我们可以摆脱这些状态和方法,因为它们在 MyProvider.js 中定义。

App.js

class App extends Component {
    render() {
        return (
            
                

Welcome to my web store

); } }
3. 创建 Consumer

我们需要再次导入 context 并用它包装我们的组件,它会在组件中注入context 参数。 之后,它非常直接。 你使用 context 就像用 props 一样。 它包含我们在 MyProducer 中共享的所有值,我们所需要做的只是去使用它!

Cars.js

const Cars = () => (
    
        {context => (
            
                

Cars:

{Object.keys(context.cars).map(carID => ( context.incrementPrice(carID)} decrementPrice={() => context.decrementPrice(carID)} /> ))}
)}
);

我们似乎忘记了什么?是 ProductList !它使好处变得非常明显。 我们不必传递任何数据或方法。这个组件被简化,因为它只需要去渲染一些组件。

ProductList.js

const ProductList = () => (
    

Product list:

{/* Other potential product categories which we will skip for this demo: */} {/* */} {/* */} {/* */}
);

在本文中,我对 Redux 和 Context API 进行了一些比较。 Redux 最大的优势之一就是你的应用可以拥有一个可以从任何组件访问的中央存储。而使用新的 Context API,默认情况下你已经有了这个功能。 在巨大的宣传攻势下 Context API 将会使 Redux 变得过时。

对于那些只把 Redux 作为中央存储功能的人来说,可能确实如此。 如果你只使用 Redux 的这一个功能,现在可以使用 Context API 替换它,并避免在不使用第三方库的情况下进行 prop drilling。

本文首发微信公众号:jingchengyideng
欢迎关注,每天都给你推送新鲜的前端技术文章

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101893.html

相关文章

  • React 328道最全面试题(持续更新)

    摘要:希望大家在这浮夸的前端圈里,保持冷静,坚持每天花分钟来学习与思考。 今天的React题没有太多的故事…… 半个月前出了248个Vue的知识点,受到很多朋友的关注,都强烈要求再出多些React相前的面试题,受到大家的邀请,我又找了20多个React的使用者,他们给出了328道React的面试题,由我整理好发给大家,同时发布在了前端面试每日3+1的React专题,希望对大家有所帮助,同时大...

    kumfo 评论0 收藏0
  • React中的Context怎么用

    摘要:怎样使用假设有个如下的结构上面的例子中,我们把手动的方式传给了,这期间穿越了,而对本身没有什么用。不建议使用绝大多数的应用程序是不需要使用的。如果项目对数据管理较为复杂,推荐使用类似于或这样的状态管理库,而不要使用。 What is Context 今天在学习styled-components的Theming时,关于styled-components对主题的实现与管理上提到,主要应用到...

    zhouzhou 评论0 收藏0
  • “别更新了,学不动了” 之:全栈开发者 2019 应该学些什么?

    摘要:但是,有一件事是肯定的年对全栈开发者的需求量很大。有一些方法可以解决这个问题,例如模式,或者你可以这么想,其实谷歌机器人在抓取单页应用程序时没有那么糟糕。谷歌正在这方面努力推进,但不要指望在年会看到任何突破。 对于什么是全栈开发者并没有一个明确的定义。但是,有一件事是肯定的:2019 年对全栈开发者的需求量很大。在本文中,我将向你概述一些趋势,你可以尝试根据这些趋势来确定你可能要投入的...

    NervosNetwork 评论0 收藏0
  • “别更新了,学不动了” 之:全栈开发者 2019 应该学些什么?

    摘要:但是,有一件事是肯定的年对全栈开发者的需求量很大。有一些方法可以解决这个问题,例如模式,或者你可以这么想,其实谷歌机器人在抓取单页应用程序时没有那么糟糕。谷歌正在这方面努力推进,但不要指望在年会看到任何突破。 对于什么是全栈开发者并没有一个明确的定义。但是,有一件事是肯定的:2019 年对全栈开发者的需求量很大。在本文中,我将向你概述一些趋势,你可以尝试根据这些趋势来确定你可能要投入的...

    sutaking 评论0 收藏0
  • “别更新了,学不动了” 之:全栈开发者 2019 应该学些什么?

    摘要:但是,有一件事是肯定的年对全栈开发者的需求量很大。有一些方法可以解决这个问题,例如模式,或者你可以这么想,其实谷歌机器人在抓取单页应用程序时没有那么糟糕。谷歌正在这方面努力推进,但不要指望在年会看到任何突破。 对于什么是全栈开发者并没有一个明确的定义。但是,有一件事是肯定的:2019 年对全栈开发者的需求量很大。在本文中,我将向你概述一些趋势,你可以尝试根据这些趋势来确定你可能要投入的...

    ormsf 评论0 收藏0

发表评论

0条评论

anRui

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<