【问题标题】:Extend Functional Components in ReactJS在 ReactJS 中扩展功能组件
【发布时间】:2021-06-16 12:26:34
【问题描述】:

我在这里有两个功能。很明显它们之间有很多重叠,我想创建一个父函数,下面的两个函数都将从中扩展。

function Home() {
  const [state, dispatch] = useContext(NTTrackerContext);
  const history = useHistory();

  function pushhistory(url, callback) {
    history.push(url);
    callback();
  }

  function teamhome2_message() {
    const info = message.error({
      content: "Log in to access team data!",
    });
  };

  function checklogin(callback) {
    if (!state.user.authenticated) 
      pushhistory("/accounts/login", function(){teamhome2_message();});
    else 
      callback();
  }
  # ...
function APIHome() {
  const [state, dispatch] = useContext(NTTrackerContext);
  const history = useHistory();

  function pushhistory(url, callback) {
    history.push(url);
    callback();
  }

  function apihome2_message() {
    const info = message.error({
      key: "apihome2",
      content: "Log in to access team API!",
    });
  };

  function checklogin(callback) {
    if (!state.user.authenticated) 
      pushhistory("/accounts/login", function(){apihome2_message();}); 
    else 
      callback();
  }
  # ...

但是,我一直在处理无效的状态/挂钩调用,没有正确创建实例。我最终不知道如何继续。

谁能提供我应该如何从父函数扩展两个home 函数的示例?

这些我看过:

  • Thread one: 没用,因为我没有使用 redux
  • Thread two:这只是关于return语句中的用法;我正在基于函数的组件中寻找return语句之外的用法。

提前致谢。

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

以下是解决问题的三种不同方法。我自己可能会选择第二种方法。

1。分享功能

一个简单的方法是将有用的函数移到函数组件之外,以便它们可以被多个组件使用。这些可以在您从Home.jsx 和APIHome.jsx 导入的实用程序文件中,但为了简单起见,我将它们编码为好像它们都在一个文件中一样。因为它们在函数组件之外,所以您需要从每个组件中传递您需要的任何数据;在这里,history。

function pushhistory(history, url, callback) {
  // added `history` argument
  history.push(url);
  callback();
}

function checklogin(state, history, loginMessage, callback) {
  // added `state`, `history`, `message` arguments
  if (!state.user.authenticated) 
    pushhistory(history, "/accounts/login", loginMessage);
  else 
    callback();
}

function Home() {
  const [state, dispatch] = useContext(NTTrackerContext);
  const history = useHistory();

  function teamhome2_message() {
    const info = message.error({
      content: "Log in to access team data!",
    });
  };

  # ...

  checklogin(state, history, teamhome2_message, callback);
}

function APIHome() {
  const [state, dispatch] = useContext(NTTrackerContext);
  const history = useHistory();

  function apihome2_message() {
    const info = message.error({
      key: "apihome2",
      content: "Log in to access team API!",
    });
  };

  # ...

  checklogin(state, history, apihome2_message, callback);
}

2。编写自己的钩子

如果你把这些助手变成钩子,你可以把useHistory推到里面,这样可以简化代码(避免传递history对象)。像这样的:

function useLogin(state, loginMessage) {
  const history = useHistory();
  if (!state.user.authenticated) {
    history.push(url);
    loginMessage();
    return false;
  }
  return true;
}

function Home() {
  const [state, dispatch] = useContext(NTTrackerContext);
  const history = useHistory();

  function teamhome2_message() {
    const info = message.error({
      content: "Log in to access team data!",
    });
  };

  const loggedIn = useLogin(state, teamhome2_message);
  if (!loggedIn) callback();

  # ...
}

function APIHome() {
  const [state, dispatch] = useContext(NTTrackerContext);
  const history = useHistory();

  function apihome2_message() {
    const info = message.error({
      key: "apihome2",
      content: "Log in to access team API!",
    });
  };

  const loggedIn = useLogin(state, apihome2_message);
  if (!loggedIn) callback();

  # ...
}

3。高阶组件

按照 cmets 中的建议,您可以编写一个生成组件的函数,并为其提供不同的参数。这是一个例子:

function homeComponent(loginMessage, ...) {
  const [state, dispatch] = useContext(NTTrackerContext);
  const history = useHistory();

  function pushhistory(url, callback) {
    history.push(url);
    callback();
  }

  function login_message() {
    const info = message.error(loginMessage);
  };

  function checklogin(callback) {
    if (!state.user.authenticated) 
      pushhistory("/accounts/login", login_message);
    else 
      callback();
  }

  # ...
}

const Home = homeComponent({
  content: "Log in to access team data!",
}, ...);

const APIHome = homeComponent({
  key: "apihome2",
  content: "Log in to access team API!",
});

但在这种情况下,您将需要更多参数来决定在每个组件的 ... 中做什么,并且您可能需要将 state 传递给它们,这最终看起来像第一种类型解决方案。

【讨论】:

  • 正是我想要的——非常感谢您的详细回答!
  • 不过,@edemaine,如果您不介意,请回答this question 好吗?这是关于第二个示例中的钩子用法。
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 2021-08-23
  • 1970-01-01
  • 2014-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-16
相关资源
最近更新 更多