I am building a roster management application. I have built a roster viewer which uses the useRosterViewer hook
.
The source code is something like:
let reducer = (state, action) => {
let result = { ...state };
switch (action.type) {
case "init":
result.roster = action.roster;
result.isLoading = false;
break;
...........
default:
break;
}
return result;
}
export function useRosterViewer() {
const [itemList, updateItemList] = useReducer(reducer, {
error: null,
isLoading: true,
roster: null,
............
});
useEffect(() => {
let getData = async () => {
let now = new Date();
let rosterYear = now.getFullYear();
let rosterMonth = now.getMonth();
let roster = await Roster(rosterYear, rosterMonth + 1);
updateItemList({
roster,
systemParam,
type: "init"
});
}
getData();
},[]);
return {
error: itemList.error,
isLoading: itemList.isLoading,
roster: itemList.roster,
.............
}
}
I am going to build a roster editor.
When I am building another hook such as useRosterEditor, the source code is something like:
export function useRosterEditor(){
const { error, isLoading, roster } = useRosterViewer();
const [itemList, updateItemList] = useReducer(reducer, {
error,
isLoading,
roster,
});
return {
error: itemList.error,
isLoading: itemList.isLoading,
roster: itemList.roster,
}
}
The following component uses the useRosterEditor:
export default function RosterEditor(){
console.log(useRosterEditor());
}
If I modify the useRosterEditor as below:
export function useRosterEditor(){
const [itemList, updateItemList] = useReducer(reducer, {
error:null,
isLoading:true,
roster:null,
});
useEffect(()=>{
let getData = async () => {
const { error, isLoading, roster } = useRosterViewer();
}
getData();
},[])
return {
error: itemList.error,
isLoading: itemList.isLoading,
roster: itemList.roster,
}
}
The react prompt the following error:
React Hook “useRosterViewer” is called in function “getData” that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word “use”
I use the useRosterViewer hook to fetch roster data for display. It works fine in the roster viewing component. In the RosterEditor component, I need to fetch the roster and other data, so I don’t want to duplicate the data-fetching code (i.e. all operations in the getData
function of the useRosterViewer hook). Therefore, I want to know
how to reuse the useRosterViewer hook in the RosterEditor component.
9
Hooks in general, cannot be called outside of a react component. Also react official document states that you cannot call hooks inside a regular js function or if statements. You can find more info here: Rules of Hooks
You can modify the useRosterEditor as below:
export function useRosterEditor(){
const [itemList, updateItemList] = useReducer(reducer, {
error:null,
isLoading:true,
roster:null,
});
const { error, isLoading, roster } = useRosterViewer();
return {
error: itemList.error,
isLoading: itemList.isLoading,
roster: itemList.roster,
}
}