Ako používať Redux v aplikácii React TypeScript

Redux je predvídateľný kontajner stavu pre aplikácie JavaScript. Je to populárna knižnica na správu stavu v aplikáciách React.

Redux môže ponúknuť lepší vývojársky zážitok, keď ho použijete spolu s TypeScript. TypeScript je nadmnožina JavaScriptu, ktorá kontroluje typ kódu tak, aby bol robustný a zrozumiteľný.

V tejto príručke vám ukážem, ako používať Redux vo svojom projekte React TypeScript vytvorením aplikácie, ktorá vám umožní pridávať, mazať a zobrazovať články.

Poďme sa ponoriť.

  • Predpoklady
  • Nastavenie
  • Vytvorte typy
  • Vytvorte typy akcií
  • Vytvorte tvorcov akcií
  • Vytvorte redukciu
  • Vytvorte obchod
  • Vytvorte komponenty

Predpoklady

Tento výukový program predpokladá, že máte aspoň základné znalosti o jazykoch React, Redux a TypeScript.

Pokiaľ teda tieto technológie nepoznáte, najskôr si prečítajte tohto praktického sprievodcu programom TypeScript alebo tento tutoriál React Redux. Inak poďme na to.

Príprava projektu

Aby sme mohli používať Redux a TypeScript, musíme vytvoriť novú aplikáciu React.

Ak to chcete urobiť, otvorme CLI (rozhranie príkazového riadku) a spustime tento príkaz:

 npx create-react-app my-app --template typescript 

Ďalej usporiadajme projekt nasledovne:

├── src | ├── components | | ├── AddArticle.tsx | | └── Article.tsx | ├── store | | ├── actionCreators.ts | | ├── actionTypes.ts | | └── reducer.ts | ├── type.d.ts | ├── App.test.tsx | ├── App.tsx | ├── index.css | ├── index.tsx | ├── react-app-env.d.ts | └── setupTests.ts ├── tsconfig.json ├── package.json └── yarn.lock 

Štruktúra súborov projektu je dosť jednoduchá. Treba si však uvedomiť dve veci:

  • storeZložka, ktorá obsahuje súbory súvisiace s Reagovať Redux.
  • type.d.tsSúbor, ktorý je držiteľom typy písacom stroji, ktoré môžu byť použité teraz v iných súboroch bez importu.

To znamená, že teraz môžeme nainštalovať Redux a vytvoriť si úplne prvý obchod.

Poďme teda otvoriť projekt a spustiť nasledujúci príkaz:

 yarn add redux react-redux redux-thunk 

Alebo pri použití npm

 npm install redux react-redux redux-thunk 

Musíme tiež nainštalovať ich typy ako vývojové závislosti, ktoré TypeScriptu pomôžu porozumieť knižniciam.

Poďme teda vykonať tento príkaz znova na CLI.

 yarn add -D @types/redux @types/react-redux @types/redux-thunk 

Alebo pre npm:

 npm install -D @types/redux @types/react-redux @types/redux-thunk 

Skvelé! Týmto krokom vpred môžeme teraz v nasledujúcej časti vytvoriť typy TypeScript pre projekt.

Vytvorte typy

Typy strojopisu vám umožňujú nastavovať typy vašich premenných, funkčných parametrov atď.

  • typ.d.ts
interface IArticle { id: number title: string body: string } type ArticleState = { articles: IArticle[] } type ArticleAction = { type: string article: IArticle } type DispatchType = (args: ArticleAction) => ArticleAction 

Tu začneme deklarovaním rozhrania, IArticlektoré odráža tvar daného článku.

Potom máme ArticleState, ArticleActiona DispatchTypeže bude slúžiť ako typy pre, respektíve stav objektu, akčné tvorcovia a funkcie odosielania poskytované Redux.

To znamená, že teraz máme potrebné typy, aby sme mohli začať používať React Redux. Vytvorme typy akcií.

Vytvorte typy akcií

  • store / actionTypes.ts
export const ADD_ARTICLE = "ADD_ARTICLE" export const REMOVE_ARTICLE = "REMOVE_ARTICLE" 

Pre obchod Redux potrebujeme dva typy akcií. Jeden na pridávanie článkov a druhý na mazanie.

Vytvorte tvorcov akcií

  • store / actionCreators.ts
import * as actionTypes from "./actionTypes" export function addArticle(article: IArticle) { const action: ArticleAction = { type: actionTypes.ADD_ARTICLE, article, } return simulateHttpRequest(action) } export function removeArticle(article: IArticle) { const action: ArticleAction = { type: actionTypes.REMOVE_ARTICLE, article, } return simulateHttpRequest(action) } export function simulateHttpRequest(action: ArticleAction) { return (dispatch: DispatchType) => { setTimeout(() => { dispatch(action) }, 500) } } 

V tomto tutoriále budem simulovať požiadavku HTTP oneskorením o 0,5 sekundy. Ak však chcete, pokojne použite skutočný server.

Tu funkcia addArticleodošle akciu na pridanie nového článku a metóda removeArticleurobí pravý opak. Takže vymažte odovzdaný objekt ako argument.

Vytvorte redukciu

Reduktor je čistá funkcia, ktorá prijíma stav obchodu a akciu ako parametre a potom vracia aktualizovaný stav.

  • store / reducer.ts
import * as actionTypes from "./actionTypes" const initialState: ArticleState = { articles: [ { id: 1, title: "post 1", body: "Quisque cursus, metus vitae pharetra Nam libero tempore, cum soluta nobis est eligendi", }, { id: 2, title: "post 2", body: "Harum quidem rerum facilis est et expedita distinctio quas molestias excepturi sint", }, ], } 

Ako vidíte tu, deklarujeme počiatočný stav, v ktorom sa majú niektoré články zobraziť pri načítaní stránky. ArticleStateStavový objekt sa musí zhodovať s typom - inak TypeScript vyhodí chybu.

  • store / reducer.ts
const reducer = ( state: ArticleState = initialState, action: ArticleAction ): ArticleState => { switch (action.type) { case actionTypes.ADD_ARTICLE: const newArticle: IArticle = { id: Math.random(), // not really unique title: action.article.title, body: action.article.body, } return { ...state, articles: state.articles.concat(newArticle), } case actionTypes.REMOVE_ARTICLE: const updatedArticles: IArticle[] = state.articles.filter( article => article.id !== action.article.id ) return { ...state, articles: updatedArticles, } } return state } export default reducer 

Next, we have the reducer function that expects the previous state and an action to be able to update the store. Here, we have two actions: one for adding and another for deleting.

With that in place, we can now handle the state with the reducer. Let's now create a store for the project.

Create a store

A Redux store is where your app's state lives.

  • index.tsx
import * as React from "react" import { render } from "react-dom" import { createStore, applyMiddleware, Store } from "redux" import { Provider } from "react-redux" import thunk from "redux-thunk" import App from "./App" import reducer from "./store/reducer" const store: Store & { dispatch: DispatchType } = createStore(reducer, applyMiddleware(thunk)) const rootElement = document.getElementById("root") render(   , rootElement ) 

As you can see, we import the reducer function and then pass it as an argument to the method createStore in order to create a new Redux store. The redux-thunk middleware needs to be proceeded as a second parameter as well to the method to be able to handle asynchronous code.

Next, we connect React to Redux by providing the store object as props to the Provider component.

We can now use Redux in this project and access the store. So, let's create the components to get and manipulate the data.

Create the components

  • components/AddArticle.tsx
import * as React from "react" type Props =  saveArticle: (article: IArticle  export const AddArticle: React.FC = ({ saveArticle }) => { const [article, setArticle] = React.useState() const handleArticleData = (e: React.FormEvent) => { setArticle({ ...article, [e.currentTarget.id]: e.currentTarget.value, }) } const addNewArticle = (e: React.FormEvent) => { e.preventDefault() saveArticle(article) } return (     Add article   ) } 

To add a new article, we will be using this form component. It receives the function saveArticle as a parameter, which allows adding a new article to the store.

The article object should follow the type IArticle to make TypeScript happy.

  • components/Article.tsx
import * as React from "react" import { Dispatch } from "redux" import { useDispatch } from "react-redux" type Props = { article: IArticle removeArticle: (article: IArticle) => void } export const Article: React.FC = ({ article, removeArticle }) => { const dispatch: Dispatch = useDispatch() const deleteArticle = React.useCallback( (article: IArticle) => dispatch(removeArticle(article)), [dispatch, removeArticle] ) return ( 

{article.title}

{article.body}

deleteArticle(article)}>Delete ) }

The Article component shows an article object.

The function removeArticle has to dispatch to access the store and hence delete a given article. That's the reason we use the useDispatch hook here, which lets Redux complete the removing action.

Next, the use of useCallback helps to avoid unnecessary re-rendering by memoizing values as dependencies.

We finally have the components we need to add and show the articles. Let's now add the last piece to the puzzle by using them in the App.tsx file.

  • App.tsx
import * as React from "react" import { useSelector, shallowEqual, useDispatch } from "react-redux" import "./styles.css" import { Article } from "./components/Article" import { AddArticle } from "./components/AddArticle" import { addArticle, removeArticle } from "./store/actionCreators" import { Dispatch } from "redux" const App: React.FC = () => { const articles: readonly IArticle[] = useSelector( (state: ArticleState) => state.articles, shallowEqual ) const dispatch: Dispatch = useDispatch() const saveArticle = React.useCallback( (article: IArticle) => dispatch(addArticle(article)), [dispatch] ) return (  

My Articles

{articles.map((article: IArticle) => ( ))} ) } export default App

The useSelector hook enables access to the state of the store. Here, we pass shallowEqual as a second argument to the method to tell to Redux to use shallow equality when checking for changes.

Next, we rely on useDispatch to dispatch an action for adding articles in the store. Finally, we loop through the array of articles and pass each to the Article component to show it.

With that, we can now browse to the root of the project and then execute this command:

 yarn start 

Or for npm:

 npm start 

If you open //localhost:3000/ in the browser, you should see this:

ukážka aplikácie

Great! Our app looks good. With this, we have now finished using Redux in a React TypeScript app.

Hotový projekt nájdete v tomto CodeSandbox.

Na mojom blogu môžete nájsť ďalší vynikajúci obsah, ako je tento, alebo ma môžete sledovať na Twitteri a dostávať upozornenia.

Vďaka za prečítanie.