【问题标题】:Is there any React JS alternative to this two function是否有任何 React JS 替代这两个功能
【发布时间】:2022-11-10 16:47:18
【问题描述】:
import { mergeProps, splitProps } from "solid-js";

我正在尝试将一个可靠的 js 应用程序转换为响应,为此我需要这两个等效的函数来响应。 如果有人可以帮助我,非常感谢他。

对于上下文,我也添加了半转换文件。

// import { styled } from "@stitches/react";
import React, {  FC, ReactNode, useMemo } from "react";
// import { mergeProps } from "react-aria";
import {   mergeProps,splitProps } from "solid-js";
// import { Dynamic } from "solid-js/web";

import { createStyledSystemClass, getUsedStylePropNames } from "../styled-system/system";
import { isFunction } from "../utils/assertion";
import { classNames, createClassSelector } from "../utils/css";
// import splitProps from "../utils/split-props";

import {
  DOMElements,
  ElementType,
  HopeComponent,
  HopeFactory,
  HopeFactoryStyleOptions,
  HTMLHopeComponents,
  HTMLHopeProps,
} from "./types";
// import {styled} from '@stitches/react'

// TODO: add stitches variant support

const styled: HopeFactory = <T extends ElementType>(
  component: T,
  styleOptions?: HopeFactoryStyleOptions<T>
) => {
  const hopeComponent: HopeComponent<T> = props => {
    const usedStylePropNames = getUsedStylePropNames(props);

    const propsWithDefault = mergeProps({as: component} , props);

    const [local, styleProps, others] = splitProps(
      propsWithDefault as HTMLHopeProps<any>,
      ["as", "class", "className", "__baseStyle"],
      usedStylePropNames
    );

    // eslint-disable-next-line react-hooks/rules-of-hooks
    const __baseStyles = useMemo(() => {
      const factoryBaseStyle = isFunction(styleOptions?.baseStyle)
        ? styleOptions?.baseStyle(props as any)
        : styleOptions?.baseStyle;

      // order is important for css override
      return [factoryBaseStyle, local.__baseStyle];
    },[local.__baseStyle, props]);

    const classes = () => {
      return classNames(
        styleOptions?.baseClass, // In order to target the component in stitches css method and prop, like any other Hope UI components.
        local.class,
        local.className,
        createStyledSystemClass(styleProps, __baseStyles)
      );
    };
    const elements: keyof JSX.IntrinsicElements = local.as ?? "div"

    const Dynamic: FC<{as: any, children: ReactNode}> = ({ as, children, ...props }) => {    
        return React.createElement(
            elements[as] || elements, 
            props, 
            children
      );
    }
    

    return <Dynamic className={classes()} {...others} >{component}</Dynamic>;
  };

  // In order to target the component in stitches css method and prop, like any other Hope UI components.
  hopeComponent.toString = () =>
    styleOptions?.baseClass ? createClassSelector(styleOptions.baseClass) : "";

  return hopeComponent;
};

function factory() {
  const cache = new Map<DOMElements, HopeComponent<DOMElements>>();

  return new Proxy(styled, {
    /**
     * @example
     * const Div = hope("div")
     * const WithHope = hope(AnotherComponent)
     */
    apply(target, thisArg, argArray: [ElementType, HopeFactoryStyleOptions<ElementType>]) {
      return styled(...argArray);
    },

    /**
     * @example
     * <hope.div />
     */
    get(_, element: DOMElements) {
      if (!cache.has(element)) {
        cache.set(element, styled(element));
      }
      return cache.get(element);
    },
  }) as HopeFactory & HTMLHopeComponents;
}

export const hope = factory();

我试过 ract-aria mergeProps() 没用,还写了一个 split props 功能也不好用。

【问题讨论】:

    标签: reactjs solid-js stitches


    【解决方案1】:

    Solid 不能使用 rest 和 spread 语法来拆分和合并 props,因为 props 对象是一个代理对象,它将属性访问转换为函数调用,以保持传递的 props 的反应性。使用... 语法拆分和合并 Solid 的道具将为您提供静态值,在此过程中丢弃代理对象。所以 Solid 需要 mergePropssplitProps 助手来提供类似的功能来传播和休息语法,同时保持反应性。

    但是,React 的 props 是普通对象,不需要代理,因为 React 会在每次状态更新时渲染整个 DOM 树。如果您还记得的话,Solid 使用实际的 DOM 元素使用细粒度的反应性,这意味着它不会渲染整个 DOM 树,而只会渲染其中状态更新的一小部分。但是 React 使用虚拟 DOM 并在每次状态更新时渲染整个 DOM,同时对先前渲染的树进行差异化和批处理以最小化工作。

    现在,要回答您的问题,您不需要在 React 中使用 mergePropssplitProps,因为其余和扩展语法为您提供了该功能。

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    
    export function App(props) {
      const { name, ...rest } = props;
      return (
        <div className='App'>
          <h1>Hello {name}!</h1>
          <p>{JSON.stringify(rest)}</p>
        </div>
      );
    }
    
    const person = {
      name: 'John Doe',
      age: 22,
      job: 'Developer',
    };
    
    ReactDOM.createRoot(document.querySelector('#root')).render(
      <App {...person} />
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-20
      • 2019-10-02
      • 2018-03-31
      • 2011-02-25
      • 2018-09-30
      • 2010-11-12
      • 1970-01-01
      相关资源
      最近更新 更多