Aquí está mi enlace useReducer inicializado en el componente de función. En la función listReducer , quiero crear un usuario ==> asigno para indicar una matriz de tipo Usuario. Entonces, en la carga útil tengo que tener User[] . Pero, cuando elimino ==> solo un elemento de ellos por _id (tuve que conformarme con el uso de una variable privada), tengo que pasar el tipo de cadena a la carga útil.
type State = {
list: User[];
}
const initialListState: State = {
list: [],
};
enum ActionKind {
CREATE = 'CREATE',
DELETE = 'DELETE',
}
type Action = {
type: ActionKind,
payload: User[] | string;
}
function listReducer(state: State, action: Action): State {
const { type, payload } = action;
switch (type) {
case ActionKind.CREATE:
return { list: action.payload };
case ActionKind.DELETE:
return {
list: state.list.filter((el) => el._id !== action.payload._id),
};
default:
return state;
}
}
export const DashBoard = () => {
const [state, dispatch] = useReducer(listReducer, initialListState);
useEffect(() => {
if (allUsers && allUsers.length > 0) {
dispatch({ type: ActionKind.CREATE,
payload: allUsers,
});
}
}, [allUsers]);
en useEffect , cuando allUsers(type User[]) se asigna a la matriz, estoy pasando allUsers a payload.
Aquí hay un error que tengo en el código actual: TS2339: Property 'list' does not exist on type 'string | User[]'.
Aquí está la interfaz de usuario
export interface User {
_id: string;
name: string;
age: string;
email: string;
password: string;
isAdmin: boolean;
}
Traté de hacer la carga útil como un objeto con propiedades separadas para id -string y list -User[]
type Action = {
type: ActionKind,
payload: {
list: User[],
id: string,
},
}
function listReducer(state: State, action: Action): State {
const { type, payload } = action;
switch (type) {
case ActionKind.CREATE:
return { list: action.payload.list };
...
y dentro useEffect
dispatch({ type: ActionKind.CREATE,
payload: {
list: allUsers,
},
});
pero de esta manera, payload.list y payload.id son campos obligatorios: múltiples errores si la declaración de tipo los hago opcionales como ==>
type Action = {
type: ActionKind,
payload: {
list?: User[],
id?: string,
},
}
entonces la list es Usuario[] | indefinido
y id es una cadena | indefinido
¿Cómo lo hago bien? Estaré encantado de cualquier ayuda
Me gusta implementar reductor como en React.js con typescript de la siguiente manera:
type State = {
x: number
y: string
z: Array<string>
}
type Payload1 = {
x: number
y: string
}
type Payload2 = {
z: Array<string>
}
type Action
= { type: "action1"; payload: Payload1 }
| { type: "action2"; payload: Payload2 }
function reducer(state: State, action: Action): State {
switch (action.type) {
case "action1":
return { ...state, x: action.payload.x, y: action.payload.y }
case "action2":
return { ...state, z: action.payload.z }
}
throw new Error("unreachable");
}
Y todo funciona bien. Entonces puedes tomar esto como referencia y crear algo como:
type Action = {
type: ActionType.CREATE
payload: User[]
} | {
type: ActionType.DELETE
payload: number
}