Struggling with the above question. Seen similar questions but cannot figure it out.
The below code is me attempting to open and close a dialog using TypeScript for first time in an existing React project which uses .js and .jsx.
import Button from '@material-ui/core/Button';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import {useDispatch, useSelector} from 'react-redux';
import {closeTsDialog} from '../actions/tsDialog'
import {ActionTypes} from '../actions/types';
const TsApp = (): JSX.Element => {
const dispatch = useDispatch();
// ERROR SHOWS UP ON LINE BELOW "state?.tsReducer?.isDialogOpen"
const isDialogOpen = useSelector(state => state?.tsReducer?.isDialogOpen);
const state = useSelector(s => s);
console.log('->>>>>> state', state);
// main tsx excluded to allow for posting on stackoverflow
};
export default TsApp;
import {TsDialogAction} from "../actions/tsDialog";
const initialState = {
id: 0,
isDialogOpen: false
};
const tsReducer = (state: TsDialogAction = initialState, action: Action) => {
switch (action.type) {
case ActionTypes.closeDialog: {
return {...state, isDialogOpen: false};
}
case ActionTypes.openDialog: {
return {...state, isDialogOpen: true};
}
default:
return state;
}
};
export default tsReducer;
import {ActionTypes} from './types';
export interface TsDialogAction { isDialogOpen: boolean number: number }
export interface CloseTsDialog { type: ActionTypes.closeDialog payload: TsDialogAction }
export interface OpenTsDialog { type: ActionTypes.openDialog payload: TsDialogAction }
export interface Increment { type: ActionTypes.increment payload: TsDialogAction }
export interface Decrement { type: ActionTypes.decrement payload: TsDialogAction }
export const closeTsDialog = (id: number) => ({type: ActionTypes.closeDialog, payload: id}); export const openTsDialog = (id: number) => ({type: ActionTypes.openDialog, payload: id}); export const incrementAction = (id: number) => ({type: ActionTypes.increment, payload: id}); export const decrementAction = (id: number) => ({type: ActionTypes.decrement, payload: id});
It is complaining about the type. Quick solution would be adding any
as state type.
Proper solution will require following two steps:
export const rootReducer = combineReducers({
dashboard: dashboardReducer,
user: userReducer
});
export type RootState = ReturnType<typeof rootReducer>
let userData = useSelector((state: RootState) => {
return state.user.data;
});
You need to declare the type of the state
argument in your selector, like:
const isDialogOpen = useSelector( (state: RootState) => state.tsReducer.isDialogOpen);
Please see the Redux docs on TypeScript usage, as well as the React-Redux docs page on static typing for examples.
(Also, as a stylistic note: please don't call that tsReducer
in your root state. Give it a name that matches the data it's handling, like state.ui
.)
If you are using react-redux, another out of the box solution would be to use RootStateOrAny
.
import { RootStateOrAny, useSelector } from 'react-redux';
// and then use it like so in your component
...
const authState = useSelector((state: RootStateOrAny) => state.auth);
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With