Day7. React组件间的通信

补充一个知识点:

  • 组件props的React内部操作

  • 一个充满疑惑的问题, 组件之间的通信

  • 假如props从super()中删掉, 可以正常显示


    正常显示.png
  • 明明没有保存props, 却有值, 为什么会有值? => 看源码


    image.png
  • 思路, 源码通篇读过, 找到对应的包, 源码不是很熟悉, 要对官方文档熟悉, API REFERENCE -> Test Renderer(告诉你这个包是干嘛的)

  • JSX转化成React.createElement


    image.png
判断, 创建element对象.png
赋值操作.png
即将过期的生命周期做了操作.png
卸载.png
  • 分析源码, 做过一个赋值
  • 为什么要这样做? React的骚操作, 担心有些人忘记在super()中给props做个保存, 保证一定有保存

组件间的通信

子组件传递父组件

  • 父组件通过props把属性传递给子组件

  • 默认值

  • 子组件发生了某一个事件, 传递到父组件

  • 某些情况, 我们也需要子组件向父组件传递消息:


    子组件传递父组件.png
  • 父组件里面定义一个函数, 把这个函数传递给子组件, 子组件里产生一个事件, 调用函数, 父组件中的函数会被回调


    子传父通信.png
  • 提一个需求, 把Button封装到一个子组件里面

  • Chrome插件 React Developer Tools

Chrome插件.png

查看.png
  • 注意this绑定! 箭头函数或bind(this)

组建通信案例练习

  • TabControl, 封装成一个组件
  • 数据的传递, 子组件传递事件到父组件
  • 非常综合的案例
  • 正规的目录结构做一个组织, App.js, 真实开发中搞一个文件夹


    案例效果.png
  • titiles要是一个数组类型, import PropTypes from 'prop-types';
  • 先对外面的东西Flex布局, 水平方向做一个等分
  • React中加样式, style.css文件, 在里面写样式
  • webpack从入口开始, 看依赖了哪些东西, 打包进去
  • 引用图结构中
  • 默认选中第一个, 需要一个记录, 点击的时候变成红色
  • 动态的添加className
  • 监听div的点击, 代码长的话需要做一个代码组织优化, 换行
  • 下划线, span包裹item添加内边距, 底部添加一个边框
  • 浮动的出现是为了做图文环绕, 不是为了做布局
.tab-control {
  display: flex;
  height: 44px;
  line-height: 44px;
}

.tab-item {
  flex: 1;
  text-align: center;
}

.tab-item span {
  padding: 5px 8px;
}

.tab-item.active {
  color: red;
}

.
  • 父组件根据子组件的选中操作, 显示文本
  • 先来到父组件里面
  • 记录的东西, 有两种方式Index、Title, 选择哪种方式根据业务需求, 用到index的场景多不多
this.state = {
  currentIndex: 0,
  currentTitle: "新款"
}

再补充一个知识点

  • Vue里面有一个插槽的功能, React里面没有这个概念
  • 真实开发中有这种需求, React实现slot
  • m.jd.com 导航的功能, 各种导航不一样, 多个页面, 多个导航, 有相似, 但是不一样
  • 开发中怎么封装这些组件? Vue预留一个插槽, 之后可以插入组件, React里面没有这个概念
  • React是非常灵活的, 根本就不需要插槽, jsx -> 数据 -> 子组件


    image.png
jsx直接传递数据到子组件.png
  • 双标签里面可以跟很多东西

  • body默认有个内边距, 要去除

  • nav-item, 做抽取

  • 开发中比较推荐的办法, 一个东西不需要在乎顺序, 如果有多个, Vue命名插槽, React索引值顺序不能乱, 另一个方案重新封装一下 NavBar2.js

  • 单标签, jsx可以做数据传递给下层的组件, 精准的拿到每一个属性


    另一种方法.png
  • 报了一个警告, link警告


    警告.png
  • 加一个路径, 消除警告ccc

  • css权重大的覆盖权重小的

  • Vue模板的限制, React非常的灵活

跨组件之间的通信, props

跨组件的通信.png
  • 一层一层的传, 比较麻烦
  • 跨组件的嵌套, Profile组件, 函数式组件也可以, 看有没有内部状态需要维护
  • $ * 4快速生成
  • 昵称之类的东西, 以后可能会发生变化 -> 放在state里面
  • 一层一层的传递有很大的一个缺陷, 中间层用不到属性, 才能传到下一层, Profile中间层用不到不应该写这些东西
  • 有一个语法, Vue里面也有, 属性展开attributes spread? 文档 -> 高级指引 -> 深入JSX -> 属性展开


    属性展开.png
  • 跟展开对象不一样, 变成了一个一个的属性, JSX语法
  • 即使做了一个简化, 但耦合性还是太多 -> Context

Context应用场景

  • 非父子组件数据的共享:


    Context应用场景.png

Context相关API

  • React.createContext
    • 创建一个需要共享的Context对象
    • 如果一个组件订阅了Context, 那么这个组件会从离自身最近的那个匹配的Provider中读取到当前的context值;
    • defaultValue是组件在顶层查找过程中没有找到对应的Provider, 那么就是用默认值


      image.png
  • Class.contextType
    • 到底指向哪一个东西


      image.png
  • 创建Context对象
// 创建Context对象
const UserContext = React.createContext({
  nickname: "aaa",
  level: -1
})]
  • 类组件有一个属性, context
  • 源码里有大量的验证代码, 看的时候可以先跳过去
  • Profile如果放到了外面, 还能展示, 不过展示的是默认数据


    默认值.png
  • 可以搞一个共享的context.js文件

考虑另一个情况, context函数式组件

  • Flutter借鉴了React
  • 特殊的语法{}
function ProfileHeader() {
  return (
    
      {
        value => {
          

用户昵称: {value.nickname}

用户等级: {value.level}

} }
) }
Consumer.png

多个Context

  • 再来做一层嵌套


    多层嵌套, 太麻烦.png
  • 真实开发中使用Redux, hooks中会有更简单的办法, 重点难点

coderwhy的React核心技术与开发实战课程链接

少年~来做同学呀~.png

你可能感兴趣的:(Day7. React组件间的通信)