I have two functions here. It's evident that there's a lot of overlap between them, and I'd like to create a parent function that both functions below will extend from.
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();
}
# ...
However, I've been dealing with invalid state/hook calls, not creating the instances correctly. I ended up having no idea how to continue.
Can anybody please provide examples of how I should extend the two home functions from a parent function?
These I have looked at:
return statements; I'm looking for usage outside the return statement in a function-based component.Thanks in advance.
Here are three different ways to approach the problem. I'd probably go for the second method myself.
A simple approach is to move your helpful functions outside of the function components, so that they can be used by multiple components. These could be in a utilities file that you import from Home.jsx and APIHome.jsx, but here I've coded them as if they're all in one file for simplicity. Because they're outside the function components, you need to pass in whatever data you need from within each component; here, 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);
}
If you turn these helpers into hooks, you can push the useHistory inside them, which simplifies the code (avoiding passing the history object). Something like this:
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();
# ...
}
As suggested in the comments, you could write a function that generates components, and give it different arguments. Here's an example of that:
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!",
});
But in this case you'll need more arguments to decide what to do in the ... of each component, and you'll probably need to pass state into them, which ends up looking like the first type of solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With