扩展 ReactJS 中的功能组件

cri*_*n24 10 javascript reactjs

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

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();
  }
  # ...
Run Code Online (Sandbox Code Playgroud)
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();
  }
  # ...
Run Code Online (Sandbox Code Playgroud)

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

有人可以提供我应该如何home从父函数扩展这两个函数的示例吗?

我看过这些:

  • 线程一:没有帮助,因为我没有使用 redux
  • 线索二:这仅涉及语句中的用法return;我正在寻找基于函数的组件中 return 语句之外的用法。

提前致谢。

ede*_*ine 12

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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();

  # ...
}
Run Code Online (Sandbox Code Playgroud)

3. 高阶组件

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

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!",
});
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,您将需要更多参数来决定在每个组件中执行哪些操作...,并且您可能需要传递state给它们,这最终看起来像第一种解决方案。