React(五)

被nvm折磨的两天,戳这里体验博主的心路历程
在这里插入图片描述
现在终于解决了,快让我记录一下,今日分心情。
在这里插入图片描述

3).context 状态树传参

​ 在平时使用react的过程中,数据都是自顶而下的传递方式,例如,如果在顶层组件(如:App)的state存储了theme主题相关的数据作为整个App的主题管理。那么在不借助任何第三方的状态管理框架的情况下,想要在子组件里获取theme数据,就必须的一层层传递下去,即使两者之间的组件根本不需要该数据。

​ Context 旨在共享一个组件树,可被视为 “全局” 的数据,达到越级传递,场景:当前经过身份验证的用户,主题或首选语言,包括管理当前的 locale,theme,或者一些缓存数据。

**createContext():**用于创建context对象(上下文),需要一个defaultValue的参数,并返回一个包含Provider(提供者),以及Consumer(消费者)的对象

Provider:提供者,提供数据。接收一个将要被往下层层传递的props,该值需在组件树最顶层设置。一个Provider可以关联到多个Consumers。这是一个顶层用于提供context的组件,包含一个value的props,value是实际的context数据。

**Consumer:**消费者,使用者,接收一个函数作为子节点,函数接收当前 context 的值。这是一个底层用于获取context的组件,需要一个函数作为其子元素,该函数包含一个value的参数,这个参数就是上层所传递context value

创建一个context组件,并设定默认值。语法如下:

 const  {Provider, Consumer} = React.createContext(defaultValue);
从父朝子传值(外朝内)

示例代码:

context组件: ./src/utils/myContext;

import {createContext} from "react";

export const {Provider, Consumer} = createContext({
  name:"张三疯"
});

//顶层组件:./src/App.js

import {Provider} from "./utils/myContext"

function App() {
  let val={
    name:"hi"
  };
  return (
    <div className="App">
      <Provider value={val}>
        <Home  />
      </Provider>
    </div>
  );
}

//孙子组件: App->Home->Goodslist
import {Consumer} from "../utils/myContext";

export default class GoodsList extends React.Component {
   
    render = () => (
        <div className="goodsList-box">
            <h1>商品列表:</h1>            
            <Consumer>
                    {
 					  (val)  => <div> { val.name } </div>
					}
            </Consumer>
        </div>
    )
}

注意:

export const {Provider, Consumer} = createContext({

​ name:“张三疯”
});

​ 这个默认值是在顶层组件没有使用Provider组件时的值,而不是,没有给value属性赋值时的值。

即:顶层组件的代码如下:

function App() {
  let val={
      name:"hi"
  };
  return (
    <div className="App">  
         <Home />
    </div>
  );
}
在子组件改变状态树的数据
//根组件:
import {Provider} from "./utils/myContext"

export default class App extends React.Component {
  constructor(props){
    super(props);  
    this.state={
        name:"宋晨",
        setName:this.fn
    } 
  }

  fn=(str)=>{
      this.setState({
        name:str
      });
  }
  
  render = () => (
    <div className="App">
      <Provider value={this.state} >
        <Home />
      </Provider>
    </div>
  )
}

//子组件里:
import {Consumer} from "../../utils/myContext";

export default class Banner extends Component {

render = () => (
  <div className="box" >
     <Consumer>
        {
           (obj)=>(
              <div>
                 <p>姓名:{obj.name}</p>
                  <input type="button" value="修改" onClick={()=>obj.setName("hiwww")} />
              </div>
          )
        }
        </Consumer>
    </div>
   )
}

高阶组件(HOC)的构建与应用

https://www.reactjscn.com/docs/higher-order-components.html

​ 高阶组件(HOC)是react中对组件逻辑进行重用的高级技术。但高阶组件本身并不是React API。它只是一种模式,这种模式是由react自身的组合性质必然产生的。

​ 具体而言,高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个新的组件,高阶组件会对传入的组件做一些通用的处理。比如:我们希望给组件的的下方增加一个版权信息,那么就可以使用高阶组件。把原始组件传入,然后,给组件增加一个版权信息后,再返回。

​ 高阶组件是通过将原组件 包裹(wrapping) 在容器组件(container component)里面的方式来组合(composes) 使用原组件。高阶组件就是一个没有副作用的纯函数。

如:
const EnhancedComponent = higherOrderComponent(WrappedComponent);
高阶函数是:higherOrderComponent
传入的组件是:WrappedComponent
返回的组件是:EnhancedComponent

示例代码:

// 带上版权的高阶函数
function withCopyRight(OldCom){
    
    class NewCom extends React.Component{      
        render() {
            return (
               <div>
                    <OldCom />
                    <hr/>
                    <div>
                        Copyright © 2020 Sohu All Rights Reserved. 搜狐公司 版权所有
                    </div>
               </div>
            );
        }
    }   
    
    return NewCom;
}

//原始组件
class CommentList extends React.Component {
  render() {      
    return (
        <div>
            新闻11111111111111111111
        </div>
    );
  }
}

//调用高阶函数后的组件
const CommentListWithCopyRight = withCopyRight(CommentList);

ReactDOM.render( <div> <CommentListWithCopyRight /></div> ,$("box"));
function $(id){
    return document.getElementById(id);
}

高阶组件的注意点(这些特点慢慢理解消化,使用其做了项目后,回过头来再看一下):

1、不要在render函数里使用高阶组件

2、必须将静态(static)方法做拷贝

​ 当使用高阶组件包装组件,原始组件被容器组件包裹,也就意味着新组件会丢失原始组件的所有静态方法,解决这个问题的方法就是,将原始组件的所有静态方法全部拷贝给新组件。

3、Refs不能传递

一般来说,高阶组件可以传递所有的props属性给包裹的组件,但是不能传递refs引用。

4、不要在高阶组件内部修改(或以其它方式修改)原组件的原型属性(prototype)。

5、约定:将不相关的props属性传递给包裹组件

6、约定:最大化使用组合

7、约定:包装显示名字以便于调试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值