React 函数组件-多层组件值传递之props父传子

React 函数组件-多层组件值传递父传子

由于本人是React新手,对于Javascript的各种传值、编写逻辑也不是很熟悉,于是在工作中遇到了这样的一个小问题:

在多层组件传值的时候,如何将父组件中的值传递到子组件中?

在此我将自己的心得体会记录下来,也因为函数组件(或者说React Hooks)区别于类组件是React17以后新增加的许多特性,而互联网上目前的使用还是以类组件为主。不过我认为函数组件更加简明,有其优越性,并且公司要求使用函数组件开发(逼着自己学),所以将自己的学习笔记记录公开,也是对函数组件的一些经验贴的小贡献。

现在我们有一个具体的场景:我们需要查询某个房间中某个库位的货物信息,库位是在父组件 HomePage 中,使用 Picker 选择器返回的值。现在我需要把这个值,传递过两层的组件,也就是到达子子组件。

最终在子子组件中,通过 data.filter() 查询的形式,将数据中的 location 字段和父组件中 Picker 选择器返回的值进行比对,查找出正确的值,并且渲染在页面上。

以上的任务,使用 React 函数组件实现。

在这里插入图片描述

我们当前的任务是,将 HomePage 产生的 location 值,传递到子组件 TransferModal, 再传递到子子组件 Transfer. 同级的 Check 和 Put 同理。

首先,可以明确的一点是,React 的父传子通信通过 props 实现。React 官网就将这种父组件传到子组件的值称为 “props”:Passing Props to a Component – React

但是,这篇文章的代码没有使用 props,这就显得比较抽象😂 文档中关于 props 的例子,都用了具体的参数名,通过花括号的方式,打包并且进行传递。不是说这种方式不好,但是当我们需要在父组件中多向子组件传一个 props 值的时候,需要在子组件的函数声明处新增加一个,会有些麻烦。

比如,考虑父组件 Profile 与子组件 Avatar:

在这里插入图片描述

假设我在父组件的 Profile 中,使用 Avatar 的时候,增加了 props 名为 a,那我如果需要在子组件中使用 a,是否需要在子组件函数的声明中,多加一个 a 呢?

而且这个花括号包裹起来的 props,并没有写一个 props 来的直接易懂。

所以对于 Avatar,我会这么写:

function Avatar(props) {
  {person, size, a} = props
  return (
  	<img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={a}
     ></img>
      )
}

发现了没,function Avatar(props) 中的 props 就是父组件传到子组件的值。那如果我需要从子组件传到子子组件,只需要在子子组件中的函数形参里面,也写一个 props,再在子组件里面传一下参数,就可以了!

具体实现:

HomePage(父组件)中:

在这里插入图片描述

其中 ref 是自定义的 React useRef。由于 TransferModal, CheckModal, PutModal 都是基于 React 的模态弹窗 Masking 组件,Masking 组件中,需要控制 setVisible 参数用于控制弹窗的弹出 / 隐藏。我们在父组件、子组件、子子组件中都需要有按钮来控制 Masking 的弹出或者关闭,所以使用 useRef 来控制 ref.current.setVisible 的值为 true 或者 false。将 ref 向下传递也是为了保证整个项目中,弹窗的弹出或者隐藏状态不随组件的改变而改变,只由用户决定。(这里只是提一下为什么 ref 这个 props 存在,可以忽略)

location 的值存储在 singleValue 中,将其赋值给 loc 并且传递给子组件。其中 TransferModal 不需要 location 值(实际项目需要),所以不传值。

CheckModal(子组件以他为例)中:

声明函数的时候,形参加入 props(ref 是因为上面的父组件中,给子组件加了一个 ref 所以分开引用,不需要加花括号)

如何获取 loc 的值?很简单:使用语句 const {loc} = props 即可获取到 loc 的值,并且传递给 Check 组件,写在其 props 部分即可。

function CheckModal(props, ref) => {
    const {loc} = props

    return <Masking
        ...props  // irrelevant code
    >
        <Check loc={loc}/>
        
    </Masking>

}

Check(子子组件)中:

const Check = (props) => {
  const {loc} = props
  let filteredData = []
  useEffect(() => {
        filteredData = data.filter((item) => item.a === loc)
    		// irrelevant code
  },[loc])
  let list = filteredData.map((item) => {
            return (
                <div key={item.id}>
                    <div>{item.name}</div>
                    <div>{item.code}</div>
                </div>
            )
        })
  return (
  	{list}
  )
}

声明函数的时候,形参加入 props

使用语句 const {loc} = props 获取 loc 的值,然后使用 useEffect 钩子,监听 loc 值的变化来根据不同的 loc 获取不同的物品信息(很正常,因为我们会按照需求获取不同库位的物品信息),再将获取的数据通过 map 方法渲染出来,最后返回。结束!

这样我们就实现了把父组件的值传到子组件再传到子子组件,附加功能有在子子组件中使用 useEffect 监听数据的动态变化并进行筛选,并 map 最终渲染。

希望我作为一个React新手,将自己学习的心路历程一步步阐释会让人觉得清楚,流程清晰。也希望大佬们对我文章中表述不规范的地方进行指正,感谢阅读!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值