javascript - Sanitizar correctamente los datos para la solicitud - Typescript, React
Fondo
No estoy seguro de cómo debería abordar la sanitización de los datos que recibo de un backend en Java para usarlos en un formulario de React. Y también al revés: sanitizar los datos que recibo de un formulario al hacer una solicitud al backend. Para la comunicación frontend/backend usamos OpenApi que genera interfaces y API en Typescript a partir de DTOs definidos en Java.
Escenario
Ejemplo del esquema en Java:
public enum Pet {
CAT,
DOG
}
@Schema(description = "Read, create or update an account")
public class AccountDto {
@NotNull
private Boolean active;
@NotBlank
private String userName;
@NotNull
private Pet preferedPet;
@Nullable
private String bioDescription;
// Constructor and getter/setters skipped
}
Implementación actual
Ejemplo de la interfaz de Typescript generada:
enum Pet {
CAT,
DOG
}
interface AccountDto {
active: boolean,
userName: string,
preferedPet: Pet,
bioDescription?: string // Translates to: string | undefined
}
Ejemplo de React.js:
import {getAccount, updateAccount, Pet, AccountDto} from "./api"
export default function UpdateAccount() {
const [formData, setFormData] = useState<AccountDto>({
active: true,
userName: "",
preferedPet: Pet.CAT,
bioDescription: ""
})
useEffect(() => {
async function fetchAccount() {
const response = await getAccount();
// Omitted error handling
setFormData(response.data);
// response.data could look like this:
// {
// active: true,
// userName: "John",
// preferedPet: Pet.DOG,
// bioDescription: null
// }
}
}, [])
async function updateAccountHandler() {
const response = await updateAccount(formData);
// Omitted error handling
// Example formData object:
// {
// active: true,
// userName: "John",
// preferedPet: Pet.CAT,
// bioDescription: ""
// }
}
return (
// All input fields
)
}
Problemas
- Al obtener la cuenta, bioDescription es
null. React mostrará una advertencia de que un componente (entrada bioDescription) está cambiando de no controlado a controlado. - Si por alguna casualidad hay una situación en la que se establece null para preferedPet, recibiremos una advertencia de que el valor seleccionado no es válido.
- Al actualizar la cuenta, todas las cadenas vacías deben ser nulas. Requerido para la base de datos y, en mi opinión, generalmente más limpio.
Preguntas
1.) Me pregunto cómo otros usuarios de React preparan/sanitizan sus datos para uso y solicitudes. ¿Hay alguna metodología o buena práctica de la que no esté al tanto?
2.) Actualmente estoy usando la siguiente función para sanear mis datos. Parece que funciona y Typescript no me notifica sobre ningún desajuste de tipos, pero creo que debería hacerlo, ya que bioDescription solo puede ser string | undefined y no null.
function sanitizeData<T>(data: T, type: "use" | "request"): T {
const sanitizedData = Object.create({});
for (const [key, value] of Object.entries(data)) {
if (!value && type === "use") {
sanitizedData[key] = "";
} else if (!value && type === "request") {
sanitizedData[key] = null;
} else {
sanitizedData[key] = value;
}
}
return sanitizedData;
}
Tengo una situación en la que estoy tratando de cambiar manualmente una prop sin usar el setState de React.
formData.description = null;
En este punto, TypeScript me está diciendo que null no es posible. Así fue como detecté que mi función de sanitización podría no ser correcta.
Demostración
Sandbox - https://codesandbox.io/s/async-cdn-7nd2m?file=/src/App.tsx