首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >解析react组件映射到新组件

解析react组件映射到新组件
EN

Stack Overflow用户
提问于 2018-03-02 08:12:36
回答 1查看 47关注 0票数 0

我正在尝试弄清楚如何将react组件作为输入并映射到新的组件树(根据需要替换标签和修改)。在这个特定的例子中,我想使用一个为DOM输出编写的组件,并将其修改为本机输出。

因此,一个非常简单的组件可能是:

代码语言:javascript
运行
复制
<MyComponent>
  <p>foo</p>
</MyComponent>

至:

代码语言:javascript
运行
复制
<MyComponent>
  <Text>foo</Text>
</MyComponent>

修改单个标签道具的加分,例如添加style道具、事件处理程序等。我知道,如果有一个答案,它不会是万能的。我只是希望得到一些关于一般方法/其他遇到这种用例并推动它向前发展的人的指导方针。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-06 23:31:18

这样的东西似乎工作得相当好,尽管在树上传递样式是一个悬而未决的问题。好吧,至少我们知道从一组标签到另一组标签的转换是可能的。Props https://stackoverflow.com/users/2578335/giles-copp

代码语言:javascript
运行
复制
// traverse.js
import React from 'react';

export function kindOf(node) {
  if (node === null || node === undefined || typeof node === 'boolean') {
    return 'Empty';
  }
  if (typeof node === 'string' || typeof node === 'number') {
    return 'Text';
  }
  if (Array.isArray(node)) {
    return 'Fragment';
  }
  const { type } = node;
  if (typeof type === 'string') {
    return 'DOMElement';
  }
  return 'ComponentElement';
}

export function defaultTraverse(path) {
  const kind = kindOf(path.node);
  if (kind === 'Empty') {
    return path.node;
  }
  if (kind === 'Text') {
    return path.node;
  }
  if (kind === 'Fragment') {
    return path.node.map(path.traverse);
  }
  return React.cloneElement(
    path.node,
    path.node.props,
    ...path.traverseChildren(),
  );
}

export default function traverse(node, visitor) {
  const {
    Empty = defaultTraverse,
    Text = defaultTraverse,
    Fragment = defaultTraverse,
    DOMElement = defaultTraverse,
    ComponentElement = defaultTraverse
  } = visitor;
  const path = {
    node,
    kindOf,
    defaultTraverse() {
      return defaultTraverse(path);
    },
    traverse(childNode, childVisitor = visitor) {
      return traverse(childNode, childVisitor);
    },
    traverseChildren(childVisitor = visitor) {
      return React.Children.toArray(path.node.props.children).map(
        (childNode) => path.traverse(childNode, childVisitor)
      );
    },
    visitor
  };
  if (node === null || node === undefined || typeof node === 'boolean') {
    return Empty(path);
  }
  if (typeof node === 'string' || typeof node === 'number') {
    return Text(path);
  }
  if (Array.isArray(node)) {
    return Fragment(path);
  }
  const { type } = node;
  if (typeof type === 'string') {
    return DOMElement(path);
  }
  return ComponentElement(path);
}

// transpile.js
import React from 'react';
import { Image, Text, View } from 'react-native';

import traverse from './traverse';

const viewNodeTypes = ['div'];
const textNodeTypes = ['h1', 'p'];
const inlineNodeTypes = ['span', 'b', 'em'];

const dom2ReactNative = (node) => traverse(node, {
  ComponentElement(path) {
    if (path.node.type === 'img') {
      return React.createElement(
        Image,
        path.node.props
      );
    }
  },
  DOMElement(path) {
    if (textNodeTypes.includes(path.node.type)) {
      return React.createElement(
        Text,
        path.node.props,
        ...path.traverseChildren(),
      );
    } else if (viewNodeTypes.includes(path.node.type)) {
      return React.createElement(
        View,
        path.node.props,
        ...path.traverseChildren(),
      );
    } else if (inlineNodeTypes.includes(path.node.type)) {
      return path.node.props.children;
    }
    return React.cloneElement(
      path.node,
      path.node.props,
      ...path.traverseChildren(),
    );
  }
});

export default dom2ReactNative;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49060805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档