【问题标题】:Two components with the same state/functions but different UI具有相同状态/功能但 UI 不同的两个组件
【发布时间】:2020-09-13 14:50:10
【问题描述】:

我有两个组件采用完全相同的道具并共享完全相同的方法。但他们有不同的用户界面。你会如何建议保持这个干燥?我的第一个想法:

  1. 创建一个具有 onClick 方法和 props/state 的 Wrapper 组件。
  2. 创建两个接受 props/state 的 UI 组件,然后根据需要进行渲染,例如:
<Wrapper>
  <UIComponent-1 />
</Wrapper>

<Wrapper>
  <UIComponent-2 />
</Wrapper>

有没有更好的方法来做到这一点?我正在考虑使包装器成为 HOC,但随后需要复制 onClick 功能(或从某个公共文件导入)。

【问题讨论】:

  • 您能分享两个组件的简化示例吗?这将有助于了解它们如何共享其功能。
  • 顺便说一句,Code Review Stack Exchange 可能是一个更好的地方发布这个:)
  • HOC 就是你想要的。 mixins 的继任者:reactjs.org/docs/higher-order-components.html@cbr 我认为在这种情况下,它非常特定于 React,对于 SO 来说并不太“固执己见”,因为它有一个由设计者为这个特定用例创建的既定方法。据我所知,codereview 也是针对实际工作的代码,而不是存根和理论。充其量它可能会去软件工程?但它太特定于 React。

标签: javascript reactjs


【解决方案1】:

这是andy mccullough's answer 的示例实现。

此示例创建一个组件,该组件包含一个可以通过调用reverse 函数反转的字符串。然后将valuereverse 函数都提供给render 属性。然后,您可以决定如何将函数附加到 DOM(如果有的话)以及值的显示位置和方式。

我还添加了一个默认的render 属性,但如果您没有默认方案,则可以将其省略。

提供给render 的函数目前是匿名函数,但如果您想重复使用它们,可以将它们存储在变量中或导出它们。

const {Fragment, useState} = React;
const {Alert, Button} = ReactBootstrap;

const defaultRender = ({value, reverse}) => <span onClick={reverse}>{value}</span>;

function Reversible({initialValue = "", render: Render = defaultRender}) {
  const [value, setValue] = useState(initialValue);
  const reverse = () => setValue(value => value.split("").reverse().join(""));
  return <Render value={value} reverse={reverse} />;
};

ReactDOM.render(
  <Fragment>
    <Reversible initialValue="default render" />
    <Reversible
      initialValue="custom Alert render"
      render={({value, reverse}) => (
        <Alert variant="primary" onMouseEnter={reverse} onMouseOut={reverse}>
          {value}
        </Alert>
      )}
    />
    <Reversible
      initialValue="custom Button render"
      render={({value, reverse}) => (
        <Button onClick={reverse}>{value}</Button>
      )}
    />
  </Fragment>,
  document.getElementById("root")
);
<link rel="stylesheet" crossorigin="anonymous" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-bootstrap@next/dist/react-bootstrap.min.js"></script>

<div id="root"></div>

【讨论】:

    【解决方案2】:

    您可以有一个常用方法的自定义钩子,然后在函数组件中调用该钩子。看起来您的问题已被指定为https://reactjs.org/docs/hooks-effect.html

    举个例子

    const useCustomHook = (someArgs) => {
     // perform some effects
     return value;
    }
    
    // Then your component
    const Component = (props) => {
    
      const value = useCustomHook(someArgs);
    
     return <div></div>
    }

    希望对你有帮助。

    【讨论】:

      【解决方案3】:

      您可以将组件拆分为多个组件。让一个组件充当 API/接口,定义可以使用的道具,并拥有一个 render 道具,它将接收您想要在特定情况下呈现的演示组件

      【讨论】:

      • 抱歉,在我的手机上缺少细节
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-17
      • 2022-10-18
      • 1970-01-01
      相关资源
      最近更新 更多