关于context:邂逅react十二-组件通信之context

对于context概念解释起来很绕,很多性能也不罕用,就简略解释一下最罕用的办法 react中跨组件通信能够通过props逐层传递或者context创建对象进行数据传递,const name=React.createContext('name')再通过订阅取值上代码~~~ //创立context对象const MyContext=React.createContext('getText')//根组件class ContextCom extends Component { state = { name:'我是大白白', level:999, content:'你好~~~~我是子组件2' } render() { return ( <div> {/* 订阅context 给state赋值 */} <MyContext.Provider value={this.state}> <Page/> </MyContext.Provider> </div> ); }}//父组件class Page extends Component { state = { } render() { return ( <div> <div> 类子组件 <PageHead/> </div> <div> 函数子组件 <Content/> </div> <div>我是内容~~~~</div> </div> ); }}//子组件1 类组件class PageHead extends Component { state = { } render() { console.log(this.context) return ( <div> <h2>name:{this.context.name}</h2> <h2>level:{this.context.level}</h2> </div> ); }}//给PageHead的contextType赋值 PageHead.contextType=MyContext//子组件2 函数组件function Content(){ return( //函数组件 取值用 Consumer <MyContext.Consumer> { value=>{ return( // **留神 函数组件中取值为 value. <div>内容:{value.content}</div> ) } } </MyContext.Consumer> )} export default ContextCom;分享结束 感激浏览 ...

July 19, 2020 · 1 min · jiezi

react-context-学习

在react 数据传递中常用的是通过props 进行数据传递,但是有的内容我们是需要在整个页面中所有的组件使用的,这个时候如果还使用props一层一层的去去传递的话就比繁琐,怎么解决这个问题呢 react提供了一个 context 上下文来解决这个问题。如果使用了react-redux 进行react中组件之间数据传递的情况,基本是不会用到context 的。 React.createContextconst MyContext = React.createContext(defaultValue);创建一个context对象,当react render一个订阅了此context的组件的时候,他将从Provider中读取context中的值 方法的第一个参数是defaultValue 参数只有在组件树种没有提供 Provider组件时使用,这可以使单独测试组件变得更方便些,注意:将undefined作为Provider值传递不会导致 consumer 组件使用defaultValue。 Context.Provider<MyContext.Provider value={/* some value */}>每一个Context对象中都包含一个Provider组件,在Provider 上有一个value 属性,这个 value 属性将能被订阅(订阅有两种方式后面会说)了context 的后代组件直接获取,这样就可以避免props向深层级的组件传递的问题了,并且订阅了context的组件,当context的值放生变化的时候组件会自动重新render Class.contextType这是一种订阅context内容的一种方法,在类的static属性contextType设置为之前创建好的context对象,在当前组件的各生命周期中使用 this.context 来访问上下文 class MyClass extends React.Component { componentDidMount() { let value = this.context; /* perform a side-effect at mount using the value of MyContext */ } componentDidUpdate() { let value = this.context; /* ... */ } componentWillUnmount() { let value = this.context; /* ... */ } render() { let value = this.context; /* render something based on the value of MyContext */ }}MyClass.contextType = MyContext;如果你使用了 public class fields syntax 也可以使用 ...

June 5, 2019 · 1 min · jiezi

Go之context包的分析

context是Go语言官方定义的一个包,称之为上下文。 Go中的context包在与API和慢进程交互时可以派上用场,特别是在提供Web请求的生产级系统中。在哪里,您可能想要通知所有goroutines停止工作并返回。 这是一个基本教程,介绍如何在项目中使用它以及一些最佳实践和陷阱。 先决条件在了解上下文之前,请先了解以下概念 goroutinechannelContext在Go语言中 context 包允许您传递一个 "context" 到您的程序,如超时或截止日期(deadline)或通道(channel),以及指示停止运行和返回等。例如,如果您正在执行Web请求或运行系统命令,那么对生产级系统进行超时控制通常是个好主意。因为,如果您依赖的API运行缓慢,您不希望在系统上备份请求,这可能最终会增加负载并降低您所服务的所有请求的性能。导致级联效应。这是超时或截止日期context可以派上用场的地方。 这里我们先来分析context源码( https://golang.org/src/contex...)。 context包的核心就是Context接口,其定义如下: type Context interface { Deadline() (deadline time.Time, ok bool) Done() <-chan struct{} Err() error Value(key interface{}) interface{}}这个接口共有4个方法: Deadline`方法是获取设置的截止时间的意思,第一个返回式是截止时间,到了这个时间点,Context会自动发起取消请求;第二个返回值ok==false时表示没有设置截止时间,如果需要取消的话,需要调用取消函数进行取消。Done方法返回一个只读的chan,类型为struct{},我们在goroutine中,如果该方法返回的chan可以读取,则意味着parent context已经发起了取消请求,我们通过Done方法收到这个信号后,就应该做清理操作,然后退出goroutine,释放资源。Err方法返回取消的错误原因,因为什么Context被取消。Value方法获取该Context上绑定的值,是一个键值对,所以要通过一个Key才可以获取对应的值,这个值一般是线程安全的。但使用这些数据的时候要注意同步,比如返回了一个map,而这个map的读写则要加锁。以上四个方法中常用的就是Done了,如果Context取消的时候,我们就可以得到一个关闭的chan,关闭的chan是可以读取的,所以只要可以读取的时候,就意味着收到Context取消的信号了,以下是这个方法的经典用法。 func Stream(ctx context.Context, out chan<- Value) error { for { v, err := DoSomething(ctx) if err != nil { return err } select { case <-ctx.Done(): return ctx.Err() case out <- v: } } }Context接口并不需要我们实现,Go内置已经帮我们实现了2个(Background、TODO),我们代码中最开始都是以这两个内置的作为最顶层的partent context(即根context),衍生出更多的子Context。 ...

May 22, 2019 · 5 min · jiezi

怎样使用React Context API

翻译:疯狂的技术宅原文: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.jsclass 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> ); }}ProductList .jsconst 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;Cars.jsconst 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>);Car.jsconst 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>);当然,这不是处理数据的最好方式,但我希望能够用它说明为什么 prop drilling 很差劲。 那么 Context API 是如何帮我们避免这种情况呢?介绍Context Web Store让我们重构程序并演示它可以做些什么。 简而言之,Context API 允许你拥有一个存储数据的中央存储(是的,就像存储在 Redux 中一样)。你可以把任何组件直接插入到商店应用中,也可以切断 middleman!重构非常简单 —— 我们不必对组件的结构进行任何修改。但是我们确实需要创建一些新组件:Provider 和 consumer。1.初始化 Context首先,我们需要创建context,后面可以使用它来创建 Provider 和 consumer。MyContext.jsimport React from ‘react’;// this is the equivalent to the createStore method of Redux// https://redux.js.org/api/createstoreconst MyContext = React.createContext();export default MyContext;2. 创建 Provider完成后,我们可以导入 context 并用它来创建我们的 provider,我们称之为 MyProvider。在里面使用一些值初始化一个状态,你可以通过 value prop 共享我们的 provider 组件。 在例子中,我们将共享 this.state.cars 以及一些操纵状态的方法。 将这些方法可以看作是 Redux 中的 Reducer。MyProvider.jsimport 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> ); }}为了使 provider 可以访问其他组件,我们需要用它包装我们的应用程序(没错,就像 Redux 一样)。我们可以摆脱这些状态和方法,因为它们在 MyProvider.js 中定义。App.jsclass 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. 创建 Consumer我们需要再次导入 context 并用它包装我们的组件,它会在组件中注入context 参数。 之后,它非常直接。 你使用 context 就像用 props 一样。 它包含我们在 MyProducer 中共享的所有值,我们所需要做的只是去使用它!Cars.jsconst 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>);我们似乎忘记了什么?是 ProductList !它使好处变得非常明显。 我们不必传递任何数据或方法。这个组件被简化,因为它只需要去渲染一些组件。ProductList.jsconst 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>);在本文中,我对 Redux 和 Context API 进行了一些比较。 Redux 最大的优势之一就是你的应用可以拥有一个可以从任何组件访问的中央存储。而使用新的 Context API,默认情况下你已经有了这个功能。 在巨大的宣传攻势下 Context API 将会使 Redux 变得过时。对于那些只把 Redux 作为中央存储功能的人来说,可能确实如此。 如果你只使用 Redux 的这一个功能,现在可以使用 Context API 替换它,并避免在不使用第三方库的情况下进行 prop drilling。本文首发微信公众号:jingchengyideng欢迎关注,每天都给你推送新鲜的前端技术文章 ...

February 20, 2019 · 3 min · jiezi