React.Children.map 递归? [英] React.Children.map recursively?

查看:38
本文介绍了React.Children.map 递归?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个用于渲染 HTML 表单的 React 组件,我发现需要递归遍历父表单组件的所有子组件,以便仅向特定类型的子组件添加额外的道具.

一个例子(在 JSX 中):

<p>个人信息</p><输入名称="first_name"/><输入名称="last_name"/><输入名称=email"/><标签>输入您的生日<输入名称=生日"类型=日期"/></标签></表格>

在这个例子中,我在我的 Form 组件中使用 React.Children.map,然后在 map 函数中我检查孩子的type"和孩子的type.displayName"以确定我的元素m 处理(原生 HTML 元素或 ReactElement):

var newChildren = React.Children.map(this.props.children, function(child) {如果(is.inArray(child.type.displayName,supportedInputTypes)){var extraChildProps = {alertColor: this.props.alertColor,显示错误:this.state.displayErrors}返回 React.cloneElement(child, extraChildProps);} 别的 {返回孩子;}}.bind(this));

我的问题是 React.Children.map 只是浅层迭代 this.props.children,我希望它也检查孩子的孩子的孩子等等.我只需要向我的 Input 组件添加道具,以便他们知道什么时候显示错误,错误信息应该显示什么颜色等等.在上面的例子中,生日输入没有收到必要的道具,因为它被包裹在一个 Label 组件中.

有没有让 React.Children.map 拥有递归"模式或任何其他可以完成我想要做的事情的实用程序的计划?

归根结底,我想编写一个函数来映射每个子节点(甚至嵌套的子节点),以便对其执行操作(在本例中为克隆).

解决方案

虽然没有融入 React,这当然是可能的:

从反应"导入反应;函数递归映射(孩子,fn){返回 React.Children.map(children, child => {如果 (!React.isValidElement(child)) {返回孩子;}如果(child.props.children){child = React.cloneElement(child, {孩子:递归映射(child.props.children,fn)});}返回 fn(child);});}

如果你想避免复制/粘贴上面的内容,你也可以使用 这个 npm 包 我创作的.

I'm building a React Component for rendering an HTML form and I'm finding the need to recursively iterate through all children of my parent Form component in order to add extra props to only children components of a certain Type.

An example (in JSX):

<Form>
    <p>Personal Information</p>
    <Input name="first_name" />
    <Input name="last_name" />
    <Input name="email" />
    <Label>
        Enter Your Birthday
        <Input name="birthday" type="date" />
    </Label>
</Form>

In this example, I'm using React.Children.map inside my Form component, and then inside the map function I'm checking the child's "type" and the child's "type.displayName" to determine what element I'm dealing with (either a native HTML element or a ReactElement):

var newChildren = React.Children.map(this.props.children, function(child) {
    if (is.inArray(child.type.displayName, supportedInputTypes)) {
      var extraChildProps = {
        alertColor: this.props.alertColor,
        displayErrors: this.state.displayErrors
      }
      return React.cloneElement(child, extraChildProps);
    } else {
      return child;
    }
  }.bind(this));

My problem is that React.Children.map only shallowly iterates through this.props.children, and I would like it to also check children of children of children, etc. I need to add props to only my Input components so that they know when to display errors, and which color the error message should be displayed, etc. In the example above, the birthday input does not receive the necessary props, because it is wrapped in a Label component.

Any plan for React.Children.map to have a "recursive" mode or any other utility out there that can accomplish what I'm trying to do?

At the end of the day, I would like to write a single function that maps through each and every child (even nested ones) in order to perform an operation on it (in this case cloning).

解决方案

While not baked into React, this is certainly possible:

import React from "react";

function recursiveMap(children, fn) {
  return React.Children.map(children, child => {
    if (!React.isValidElement(child)) {
      return child;
    }

    if (child.props.children) {
      child = React.cloneElement(child, {
        children: recursiveMap(child.props.children, fn)
      });
    }

    return fn(child);
  });
}

If you'd like to avoid copy / pasting the above you can also use this npm package I authored.

这篇关于React.Children.map 递归?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆