Updated March 31, 2023
Introduction to React Redux TypeScript
TypeScript can be defined as an advanced subset of JavaScript. If one has an interest in going towards a statistical type of language or one is a JavaScript developer, then TypeScript is considered as the best language to choose. If a developer hasn’t written in statically typed languages like Go, JVM’s, C, etc. then using TypeScript is considered as the best logical move for developers who are comfortable with JavaScript. In this topic, we are going to learn about React Redux Typescript. To a Redux Application, TypeScript offers benefits like:
- For typed code, very easy recording.
- It provides a great experience for the developer in a great team environment.
- Type safety for UI components, action and state creators, and reducers.
How React Redux is done with Examples?
Chat Bot Application
Components inside src folder–
- stock folder
- Application.tsx
- HistoryofChat.tsx
- InterfaceofChat.tsx
- index.tsx
- maincontent.css
- thunk.css
Components inside the stock folder-
- conversation folder
- structure folder
- index.ts
Components inside conversation folder-
- activity.ts
- conv_reducers.ts
- kind.ts
Components inside structure folder-
- activity.ts
- kind.ts
- struc_reducers.ts
1. activity.ts (*conversation folder*)
import { Message, SEND_MESSAGE, DELETE_MESSAGE } from "./kind";
export function sendMessage(newMessage: Message) {
return {
type: SEND_MESSAGE,
payload: newMessage
};
}
export function deleteMessage(timestamp: number) {
return {
type: DELETE_MESSAGE,
meta: { timestamp
}
};
}
2. conv_reducers.ts (*conversation folder*)
import { ChatState, SEND_MESSAGE, DELETE_MESSAGE, ChatActionTypes } from "./kind";
const initialState: ChatState = {
messages: []
};
export function chatReducer(
state = initialState,
action: ChatActionTypes
): ChatState {
switch (action.type) {
case SEND_MESSAGE:
return {
messages: [...state.messages, action.payload]
};
case DELETE_MESSAGE:
return {
messages: state.messages.filter(
message => message.timestamp !== action.meta.timestamp
)
};
default: return state;
}
}
3. kind.ts (*conversation folder*)
export interface Message {
user: string;
message: string;
timestamp: number;
}
export interface ChatState {
messages: Message[];
}
export const SEND_MESSAGE = "SEND_MESSAGE";
export const DELETE_MESSAGE = "DELETE_MESSAGE";
interface SendMessageAction {
type: typeof SEND_MESSAGE;
payload: Message;
}
interface DeleteMessageAction {
type: typeof DELETE_MESSAGE;
meta: {
timestamp: number;
};
}
export type ChatActionTypes = SendMessageAction | DeleteMessageAction;
4. activity.ts (*structure folder*)
import { SystemState, UPDATE_SESSION } from "./kind";
export function updateSession(newSession: SystemState) {
return {
type: UPDATE_SESSION,
payload: newSession
};
}
5. kind.ts (*structure folder*)
export interface SystemState {
loggedIn: boolean;
session: string;
userName: string;
}
export const UPDATE_SESSION = "UPDATE_SESSION";
interface UpdateSessionAction {
type: typeof UPDATE_SESSION;
payload: SystemState;
}
export type SystemActionTypes = UpdateSessionAction;
6. struc_reducers.ts (*structure folder*)
import { UPDATE_SESSION, SystemState, SystemActionTypes } from "./kind";
const initialState: SystemState = {
loggedIn: false,
session: "",
userName: ""
};
export function systemReducer(
state = initialState,
action: SystemActionTypes
): SystemState {
switch (action.type) {
case UPDATE_SESSION: {
return {
...state,
...action.payload
};
}
default:
return state;
}
}
7. index.ts (*stock folder*)
import { createStore
, combineReducers
, applyMiddleware } from "redux";
import thunkMiddleware from "redux-thunk";
import { composeWithDevTools } from "redux-devtools-extension";
import { systemReducer } from "./structure/struc_reducers";
import { chatReducer } from "./conversation/conv_reducers";
const rootReducer = combineReducers({
system: systemReducer,
chat: chatReducer
});
export type AppState = ReturnType<typeof rootReducer>;
export default function configureStore() {
const middlewares = [thunkMiddleware];
const middleWareEnhancer = applyMiddleware(...middlewares);
const store = createStore(
rootReducer,
composeWithDevTools(middleWareEnhancer)
);
return store;
}
8. Application.tsx (*src folder*)
import * as React from "react";
import { connect } from "react-redux";
import { AppState } from "./stock";
import "./maincontent.css";
import { SystemState } from "./stock/structure/kind";
import { updateSession } from "./stock/structure/activity";
import { ChatState } from "./stock/conversation/kind";
import { sendMessage } from "./stock/conversation/activity";
import ChatHistory from "./HistoryofChat";
import ChatInterface from "./InterfaceofChat";
import { thunkSendMessage } from "./thunks";
interface AppProps {
sendMessage: typeof sendMessage;
updateSession: typeof updateSession;
chat: ChatState;
system: SystemState;
thunkSendMessage: any;
}
export type UpdateMessageParam = React.SyntheticEvent<{ value: string }>;
class App extends React.Component<AppProps> {
state = {
message: ""
};
componentDidMount() {
this.props.updateSession({
loggedIn: true,
session: "visitor_session",
userName: "Visitor"
});
this.props.sendMessage({
user: "Ritika the Chat Bot",
message: "I am your Assistance. How can I help you?",
timestamp: new Date().getTime()
});
this.props.thunkSendMessage("This message was sent by Chat Bot!");
}
updateMessage = (event: UpdateMessageParam) => {
this.setState({ message: event.currentTarget.value });
};
sendMessage = (message: string) => {
this.props.sendMessage({
user: this.props.system.userName,
message: message,
timestamp: new Date().getTime()
});
this.setState({ message: "" });
};
render() {
return (
<div className="parent">
<ChatHistory messages={this.props.chat.messages} />
<ChatInterface userName={this.props.system.userName}
message={this.state.message}
updateMessage={this.updateMessage}
sendMessage={this.sendMessage}
/>
</div>
);
}
}
const mapStateToProps = (state: AppState) => ({ system: state.system,
chat: state.chat
});
export default connect( mapStateToProps,
{ sendMessage, updateSession, thunkSendMessage }
)(App);
9. HistoryofChat.tsx (*src folder*)
import * as React from "react";
import { Message } from "./stock/conversation/kind";
interface ChatHistoryProps {
messages: Message[];
}
const ChatHistory: React.SFC<ChatHistoryProps> = ({ messages }) => {
return (
<div className="chat-history">
{messages.map(message => (
<div className="message-item" key={message.timestamp}>
<h3>From: {message.user}</h3>
<p>{message.message}</p>
</div>
))}
</div>
);
};
export default ChatHistory;
10. InterfaceofChat.tsx (*src folder*)
import * as React from "react";
import { UpdateMessageParam } from "./Application";
interface ChatInterfaceProps {
message: string;
userName: string;
sendMessage: (message: string) => void;
updateMessage: (event: UpdateMessageParam) => void;
}
const ChatInterface: React.SFC<ChatInterfaceProps> = ({ userName,
message, updateMessage, sendMessage
}) => {
function keyPress(e: React.KeyboardEvent<any>) {
if (e.key === "Enter") { send();
}
}
function send() {
sendMessage(message);
}
return (
<div className="chat-interface">
<h3>User: {userName} </h3>
<input
value={message}
onChange={updateMessage}
onKeyPress={keyPress}
className="chat-input"
placeholder="Please Enter your Message..."
/>
<button onClick={send}>Click To Send</button>
</div>
);
};
export default ChatInterface;
11. index.tsx (*src folder*)
import * as React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import configureStore from "./stock";
import Application from "./Application";
const store = configureStore();
const Root = () => (
<Provider store={store}>
<Application />
</Provider>
);
render(<Root />, document.getElementById("root"));
12. maincontent.css (*src folder*)
html,
body,
#root {
padding: 1;
margin: 1;
height: 99%;
line-height: 1.6;
font-size: 17px;
font-family: sans-serif, Helvetica;
color: #333330;
background-color: #c3ed74;
}
.parent {
height: 99%;
display: flex;
flex-flow: column;
}
.chat-history {
flex: 2;
overflow-y: auto;
}
.chat-interface {
border-top: 2px solid #5f6357;
background-color: #fff987;
padding: 11px;
}
.chat-interface h3 {
margin: 0.1;
}
.chat-interface input {
width: 41%;
padding: 11px 16px;
}
.chat-interface button {
cursor: pointer;
padding: 11px 16px;
font-size: 1em;
border: 1;
user-select: none;
outline: none;
color: #f0efeb;
background-color: #d11f72;
border-bottom-right-radius: 6px;
border-top-right-radius: 6px;
}
.message-item {
background-color: #f5e9ee;
margin: 11px 11px;
border: 2px solid #99878e;
padding: 13px 5px;
border-radius: 6px;
}
.message-item h3,
.message-item p {
margin: 0;
}
13. thunks.ts (*src folder*)
import { Action } from "redux";
import { ThunkAction } from "redux-thunk";
import { sendMessage } from "./stock/conversation/activity";
import { AppState } from "./stock";
export const thunkSendMessage = (
message: string
): ThunkAction<void, AppState, null, Action<string>> => async dispatch => {
const asyncResp = await exampleAPI();
dispatch(
sendMessage({
message,
user: asyncResp,
timestamp: new Date().getTime()
})
);
};
function exampleAPI() {
return Promise.resolve("Async Chat Bot");
}
Output:
Conclusion
On the basis of the above discussion, we got to know about TypeScript, the benefits offered by TypeScript and when & by whom TypeScript is used. The React Redux TypeScript-based Chat application has been successfully developed above.
Recommended Articles
This is a guide to React Redux Typescript. Here we discuss the introduction and how React Redux is done with Examples and code implementation. You may also look at the following articles to learn more –