为(点击处理程序)函数创建辅助函数以在多个 React 组件中重用

Create helper function for a (click handler) function to reuse in multiple React components

对于 'back' 我在我的 React 应用中创建的按钮 (onClick) 处理函数。

  const { length: historyLength, goBack, replace } = useHistory();

  const handleBack = () => {
    if (historyLength > 2) {
      goBack();
    } else {
      // History length is 2 by default when nothing is pushed to history yet
      // 
      replace(HomePage);
    }
  };

然后我将 onClick 处理程序传递给我的子组件,例如:<Button onClick={handleBack}/>

我在我的 React 应用程序的多个地方使用这个 handleBack 函数。这是一个好的方法吗?一个辅助函数,具体如何?

@meez

不明白为什么这行不通。只有几件事:(a)我会在函数中添加事件参数和 e.preventDefault() 并且(b)会小心你传递给 onClick 属性 的函数名称你的按钮:handleBackClick !== handleBack,你会得到一个 ReferenceError 因为一个未定义的函数。

此外,我还注意到,这可以通过浏览器的原生功能来实现。这是一个片段:

const { length: historyLength, back } = window.history;
const { replace } = window.location;

const handleBack = (e) => {
  e.preventDefault();
  if (historyLength > 2) {
    back();
  } else {
    replace('homepageUrl');
  }
};

我也没有发现代码或将其用作实用程序回调有任何问题。

Is it a good approach make it e.g. a helper function and how exactly?

任何时候你都可以让你的代码更DRY不要重复自己)这通常是一件好事。我个人的 rule-of-thumb 是,如果我第三次编写相同的实用程序代码,我会花一点时间将其重构为通用实用程序(和单元测试!!).

我可能会建议为 return 后处理程序创建一个自定义挂钩。

示例:

import { useHistory } from 'react-router-dom';

const useBackHandler = () => {
  const history = useHistory();

  const handleBack = React.useCallback(() => {
    const { length: historyLength, goBack, replace } = history;

    if (historyLength > 2) {
      goBack();
    } else {
      replace(HomePage);
    }
  }, []);

  return handleBack;
};

export default useBackHandler;

现在您可以导入和使用一个挂钩。

import useBackHandler from '../path/to/useBackHandler';

...

const backHandler = useBackHandler();

...

<button type="button" onClick={backHandler}>Back?</button>

如果您需要在较旧的 class 组件中使用此功能,那么您将需要一种方法将 handleBack 作为道具注入。为此,您可以创建一个高阶组件。

示例:

import useBackHandler from '../path/to/useBackHandler';

const withBackHandler = Component => props => {
  const backHandler = useBackHandler();
  return <Component {...props} backHandler={backHandler} />;
};

export default withBackHandler;

要使用,导入 withBackHandler 并装饰一个 React 组件并访问 props.backHandler

import withBackHandler from '../path/to/withBackHandler';

class MyComponent extends React.Component {
  ...

  someFunction = () => {
    ...
    this.props.backHandler();
  }

  ...
}

export default withBackHandler(MyComponent);