Búsqueda de sitios web

reactjs - Escribiendo mapStateToProps en React Redux


No puedo escribir el parámetro "state" de un mapStateToProps

Si simplemente cambio state : any en lugar de state: AppState, funciona y no hay error. Pero me gustaría tener un tipeado correcto para mi parámetro state.

Por ahora, tengo este error en el parámetro mapStateToProps de connect()

Ninguna sobrecarga coincide con esta llamada. La última sobrecarga dio el siguiente error. Argumento de tipo '(state: { quiz: IQuizInitialState; }) => StateProps' no es asignable al parámetro de tipo 'MapStateToPropsParam'. No se puede asignar el tipo '(state: { quiz: IQuizInitialState; }) => StateProps' al tipo 'MapStateToPropsFactory'. Los parámetros 'state' e 'initialState' no son compatibles. La propiedad 'quiz' falta en el tipo '{}' pero es requerida en el tipo '{ quiz: IQuizInitialState; }'.ts(2769)

interface OwnProps {

}
interface StateProps {

}
interface DispatchProps {

}

type Props = OwnProps & StateProps & DispatchProps;


export class App extends Component<Props> {

  render() {
    return (
     <div>Hey</div>
    );
  }
}

const mapStateToProps = (state: AppState): StateProps => ({ 
})

const mapDispatchToProps = (dispatch: ThunkDispatch<{}, {}, AnyAction>): DispatchProps => {
    return {
    }
}


// The args 'mapStateToProps' generate the error
export default connect<StateProps,DispatchProps,OwnProps>(mapStateToProps, mapDispatchToProps)(App)

Este es mi rootReducer :

import { combineReducers } from 'redux';
import { QuizReducer } from './quiz';

const rootReducer = combineReducers({
    quiz: QuizReducer
});

export type AppState = ReturnType<typeof rootReducer>


export default rootReducer;

Y el reductor único es:

import { TYPES } from '../actions/action-types';
import { IQuizListItem, Action } from '../models/index';
import { AnyAction } from 'redux';


export interface IQuizInitialState {
    quizListItem: IQuizListItem[]
}
const quizInitialState: IQuizInitialState = {
    quizListItem: []
}
export const QuizReducer = (state = quizInitialState, action: AnyAction): IQuizInitialState => {
    switch (action.type) {
        case TYPES.getQuizListItems:
            return {
                ...state,
                quizListItem: (action as Action<IQuizListItem[]>).payload
            }

        default:
            return state
    }
}

¡Gracias de antemano, chicos!

Respuesta #1

El tipo de tu estado es el mismo tipo que usas para todo el estado, ya que mapStateToProps toma todo el estado para pasarlo a los selectores. En tu caso, creo que este sería el tipo correcto IQuizInitialState.

const mapStateToProps = (state: IQuizInitialState): StateProps => ({ 

})

EDITAR

En tu comentario mencionas que IQuizInitialState no es todo el estado de tu aplicación. Entonces ese no es el que necesitas. Necesitas un tipo para todo el estado de la aplicación. Para lograr eso, podrías crear una interfaz para cada tipo de reductor, es decir, tu IQuizInitialState pero para los otros reductores en una sola interfaz.

Tendré que asumir aquí ya que no tengo tu base de código, pero considera

combineReducers({potato: quizReducer, tomato: otherReduzer})

necesitarás un tipo

interface IApplicationState {
potato: IQuizInitialState;
tomato: IOTherInterfaceYouDefinedForThisReducer;
}

tu combineReducers probablemente se verá así:

combineReducers<IApplicationState>({
  potato: quizReducer,
  tomato: otherReduzer
});

Espero que entiendas la idea.

EDIT 2 Después de leer tu último comentario, noté que estás pidiendo el mapStateToProps con dos argumentos, y solo estás definiendo uno. Tus genéricos de connect parecen estar mal entonces. Deberías considerar lo siguiente:

connect<StateProps, DispatchProps, Props, IApplicationState>

dónde :

  • StateProps: describe lo que fue devuelto por mapStateToProps()
  • DispatchProps: describe lo que devuelve dispatchToProps()
  • Props: Las props de tu componente
  • IApplicationState: Representa el estado completo de Redux de tu aplicación

Artículos relacionados