アプリ全体で再利用するカスタム フックを作成していますが、コード内のコメントからわかるように、予期しない結果が得られました。 console.log しかし、それらは2回ディスパッチされ、状態の値を取得しようとしたときに、いくつかのアクションをディスパッチした後、期待される状態を取得できませんでした。デフォルトのものを取得しました。
import { useReducer, useCallback, useState } from "react";
import { functions } from "../base";
const initialState = {
to: [],
cc: [],
bcc: [],
data: {},
subject: "",
};
const SET_RECIEPENTS = "SET_RECIEPENTS";
const ADD_RECIEPENT = "ADD_RECIEPENT";
const SET_SUBJECT = "SET_SUBJECT";
const SET_CC = "SET_CC";
const ADD_CC = "ADD_CC";
const SET_BCC = "SET_BCC";
const ADD_BCC = "ADD_BCC";
const SET_DATA = "SET_DATA";
const RESET = "RESET";
const emailReducer = (state, action) => {
console.log("prevState: ", state); // logs state
console.log("action: ", action); // called twice with the expected type and payload and triggers state change
switch (action.type) {
case SET_RECIEPENTS:
if (!action.reciepents instanceof Array) {
throw new Error("reciepents must be an Array");
}
return {
...state,
to: [...action.reciepents],
};
case ADD_RECIEPENT:
if (typeof action.reciepent !== "string" || action.reciepent === "") {
throw new Error("the reciepent must be a string");
}
return { ...state, to: [...state.to, action.reciepent] };
case SET_SUBJECT:
if (typeof action.subject !== "string" || action.subject === "") {
throw new Error("Subject must be a string");
}
return {
...state,
subject: action.subject,
};
case SET_CC:
if (!action.cc instanceof Array) throw new Error("CC must be an Array");
return {
...state,
cc: [...action.cc],
};
case ADD_CC:
if (typeof action.cc !== "string" || action.cc === "") {
throw new Error("the CC must be a string");
}
return {
...state,
cc: [...state.cc, action.cc],
};
case SET_BCC:
if (!action.bcc instanceof Array) throw new Error("BCC must be an Array");
return {
...state,
bcc: [...action.bcc],
};
case ADD_BCC:
if (typeof action.bcc !== "string" || action.bcc === "") {
throw new Error("the BCC must be a string");
}
return {
...state,
bcc: [...state.bcc, action.bcc],
};
case SET_DATA:
if (typeof action.data !== "object") {
throw new Error("Data must be a object");
}
return {
...state,
data: { ...action.data },
};
case RESET:
return { ...initialState };
default:
throw new Error(`Unhandled action type: ${action.type}`);
}
};
const useSendEmail = (templateId, cb = function () {}) => {
if (!templateId || templateId === "" || typeof templateId !== "string") {
throw new Error("please provide a valid template id");
}
const [state, dispatch] = useReducer(emailReducer, initialState);
const [error, setError] = useState(null);
const { to } = state;
const setReciepents = useCallback(
(reciepents) => dispatch({ type: SET_RECIEPENTS, reciepents }),
[]
);
const addReciepent = useCallback(
(reciepent) => dispatch({ type: ADD_RECIEPENT, reciepent }),
[]
);
const setSubject = useCallback(
(subject) => dispatch({ type: SET_SUBJECT, subject }),
[]
);
const setCC = useCallback((cc) => dispatch({ type: SET_CC, cc }), []);
const addCC = useCallback((cc) => dispatch({ type: ADD_CC, cc }), []);
const setBCC = useCallback((bcc) => dispatch({ type: SET_BCC, bcc }), []);
const addBCC = useCallback((bcc) => dispatch({ type: ADD_BCC, bcc }), []);
const setData = useCallback((data) => dispatch({ type: SET_DATA, data }), []);
const reset = useCallback(() => dispatch({ type: RESET }), []);
const sendEmail = useCallback(() => {
console.log({state}) // returns the default state
if (to && to.length > 1) {
console.log({state}) // never runs becuase there aren't emails in to []
try {
const sendEmailFunction = functions.httpsCallable().sendEmail;
sendEmailFunction({ ...state, templateId })
.then(() => {
cb({ ...state });
})
.catch((err) => {
setError(err);
});
} catch (err) {
setError(err);
}
}
}, []);
return {
setReciepents,
addReciepent,
setSubject,
setCC,
addCC,
setBCC,
addBCC,
setData,
reset,
sendEmail,
error,
};
};
export default useSendEmail;
コンポーネントでは、このフックコードを使用しました
const {
sendEmail,
error,
addReciepent,
addCC,
addBCC,
setSubject,
setData,
} = useSendEmail("ID", () => {
setSucces(true);
});
const handleAddEmail = () => {
if (email !== "") {
setEmailsList((list) => [...list, email]);
addReciepent(email);
setEmail("");
}
};
const handleAddCC = () => {
if (cc !== "") {
setCCList((list) => [...list, cc]);
addCC(cc);
setCCValue("");
}
};
const handleAddBCC = () => {
if (bcc !== "") {
setBCCList((list) => [...list, bcc]);
addBCC(bcc);
setBCCValue("");
}
};
const handleSubmit = async (event) => {
event.preventDefault();
console.log("Submit");
setSubject(subject);
setData({ name, place });
sendEmail();
};
私は本当にこのカスタムフックアプローチを続けたいと思っていますが、これらのバグは誰かが助けてくれることを本当に願っています. ありがとう