工作中八股文是否有用?对象转字符串绕过react框架限制

场景

公司大佬们封装了一个ui框架,平时开发都是用这个ui框架,其中表格组件有列配置功能,类似下图(这是ruoyi-plus-vben的demo,公司框架不方便展示) 列配置展示的name对应表头title,

css 复制代码
Columns:{
...,
title:React.ReactNode
}

ColumnConfiguration : {
...,
name:String
}
透传参的方式简化版本:
<Table columns={columns:Columns} />
columnConfiguration.name = `${columns.title}`

正常情况完美显示也实现了功能

这时产品经理来了一个需求 能不能再表头上面加个问号,鼠标移上去显示一些信息

翻译过来就是这样一个需求(用图层软件模拟了一下)

这是一个简单需求,因为title:React.ReactNode所以直接传入一个reactNode给title属性就行了

xml 复制代码
title:
<Space>
    状态
    <Tooltip mini content='123456789'>  
        <IconQuestionCircle />
    </Tooltip>
</Space>

好了完美显示,自测一下关联功能就能提交git了

问题

咦?什么情况(这时候是懵的,一步步看组件源码看的头晕眼花)为什么会这样呢,看这个样子是对象转字符串的问题,查阅组件源码后才发现接收方式

从复杂源码定位到这里后已经是半小时后了,算分析到了原因,那么就是解决方案了。

解决方案

最简单的方案就是让大佬改一下框架来兼容,想了一个最简单的方案 columns再加一个字段settingKey去给columnConfiguration.name做匹配,又转念一想这是谁都能想到的方案,有没有不破坏现有框架去解决呢。

分析问题

reactNode是一个对象,但是columnConfiguration.name是一个字符串使用了模版字符串去接收,这就涉及到了对象如何转化成字符串了:

对象是如何转字符串的

来看看ai怎么回答:

markdown 复制代码
### 对象到字符串的转换规则

1.  **优先调用 `toString()` 方法**:

    -   如果对象具有 `toString()` 方法,并且该方法返回一个原始值,则将该原始值转换为字符串并返回。

2.  **次选调用 `valueOf()` 方法**:

    -   如果对象没有 `toString()` 方法,或者 `toString()` 方法返回的不是原始值,则调用 `valueOf()` 方法。
    -   如果 `valueOf()` 方法返回一个原始值,则将该原始值转换为字符串并返回。

3.  **抛出 TypeError 异常**:

    -   如果 `toString()` 和 `valueOf()` 方法都无法提供原始值,则会抛出类型错误异常。

回答的对也不对,其实最严谨的来说其实是查找了对象的Symbol.toPrimitive 方法,Symbol.toPrimitive再去依次执行前面123步骤

尝试独立解决

想到了思路就打开了,既然是一个对象,那么我重写对象的Symbol.toPrimitive方法就行了

javascript 复制代码
const StatusNode = () => (
     <Space>
       状态
       <Tooltip mini content='123456789'>
         <IconQuestionCircle />
       </Tooltip>
     </Space>
)
const customStatusNode = React.createElement(StatusNode, null);
customStatusNode[Symbol.toPrimitive] = () => '状态';

reactNode不能修改这个属性,这时候想到了之前去覆盖dom的style属性(style不能直接 dom.style = {...}),使用了 Object.assign()

css 复制代码
Object.assign(customStatusNode, {[Symbol.toPrimitive]: () => '状态'})

好吧这个对象被设置了不可扩展,对象一旦被设置为不可扩展(non-extensible),就无法再将其转换为可扩展(extensible)得转换思路了,

又是各种查阅资料与翻阅文档,十分钟后灵光一现,我创建一个新对象不就行了!

javascript 复制代码
const customNode  = {...customStatusNode,[Symbol.toPrimitive]: () => '类型'}
title:customNode

《完美解决》,高兴了半天巴不得上班时候就发一篇文章记录下来。

封装函数

javascript 复制代码
const rewriteToPrimitive = (reactNode:React.ReactNode,title:String) => {
  const customNode = React.createElement(reactNode, null);
  return {...customNode,[Symbol.toPrimitive]: () => title}
}

title:rewriteToPrimitive(reactNode,title)

大佬出手

javascript 复制代码
import React, {isValidElement} from "react";

export const getTextFromReactNode = (node: React.ReactNode): string => {
    if (typeof node === 'string' || typeof node === 'number') {
        return String(node);
    }
    if (Array.isArray(node)) {
        return node.map(getTextFromReactNode).join('');
    }
    if (isValidElement(node)) {
        const { children } = node.props;
        return getTextFromReactNode(children);
    }
    return '';
};
columnConfiguration.name = getTextFromReactNode(columns.title)

大佬就是大佬,希望往后也能在ui框架里留下痕迹

相关推荐
Web打印2 分钟前
HttpPrinter是一款基于HTTP协议的跨平台Web打印解决方案,
javascript·php
少油少盐不要辣8 分钟前
前端如何处理AI模型返回的流数据
前端·javascript·人工智能
跟着珅聪学java11 分钟前
以下是使用JavaScript动态拼接数组内容到HTML的多种方法及示例:
开发语言·前端·javascript
巴拉巴拉~~19 分钟前
KMP 算法通用图表组件:KmpChartWidget 多维度可视化 + PMT 表渲染 + 性能对比
前端·javascript·microsoft
智算菩萨25 分钟前
基于spaCy的英文自然语言处理系统:低频词提取与高级文本分析
前端·javascript·easyui
刘一说35 分钟前
Vue单页应用(SPA)开发全解析:从原理到最佳实践
前端·javascript·vue.js
疯狂成瘾者37 分钟前
前端vue核心知识点
前端·javascript·vue.js
hh随便起个名9 小时前
力扣二叉树的三种遍历
javascript·数据结构·算法·leetcode
我是小路路呀9 小时前
element级联选择器:已选中一个二级节点,随后又点击了一个一级节点(仅浏览,未确认选择),此时下拉框失去焦点并关闭
javascript·vue.js·elementui
敲敲了个代码10 小时前
隐式类型转换:哈基米 == 猫 ? true :false
开发语言·前端·javascript·学习·面试·web