Kuinka käyttää Reduxia React TypeScript -sovelluksessa

Redux on ennakoitavissa oleva Java-sovellusten kontti. Se on suosittu kirjasto valtionhallintaan React-sovelluksissa.

Redux voi tarjota paremman kehittäjäkokemuksen, kun käytät sitä yhdessä TypeScriptin kanssa. TypeScript on JavaScriptin yläjoukko, joka tarkistaa koodin tyypin vahvaksi ja ymmärrettäväksi.

Tässä oppaassa näytän sinulle, kuinka Reduxia käytetään React TypeScript -projektissasi rakentamalla sovellus, jonka avulla voit lisätä, poistaa ja näyttää artikkeleita.

Sukelletaan sisään.

  • Edellytykset
  • Asettaa
  • Luo tyypit
  • Luo toimintotyypit
  • Luo toiminnan luojat
  • Luo vähennysventtiili
  • Luo myymälä
  • Luo komponentit

Edellytykset

Tässä opetusohjelmassa oletetaan, että sinulla on ainakin perustiedot Reactista, Reduxista ja TypeScriptistä.

Joten, jos et ole perehtynyt näihin tekniikoihin, yritä ensin lukea tämä käytännön opas TypeScriptiin tai tämä React Redux -opetusohjelma. Muuten aloitetaan.

Projektin perustaminen

Reduxin ja TypeScriptin käyttämiseksi meidän on luotava uusi React-sovellus.

Voit tehdä niin avaamalla CLI: n (komentoriviliitäntä) ja suorittamalla tämän komennon:

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

Rakennetaan seuraavaksi projekti seuraavasti:

├── 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 

Projektin tiedostorakenne on melko yksinkertainen. On kuitenkin otettava huomioon kaksi asiaa:

  • storeKansio, joka sisältää liittyvät tiedostot reagoida Redux.
  • type.d.tsTiedosto, joka pitää konekirjoituskirjaimin tyyppejä, joita voidaan käyttää nyt muita tiedostoja tuomatta.

Siitä huolimatta voimme nyt asentaa Reduxin ja luoda ensimmäisen myymälämme.

Joten, avataan projekti ja suoritetaan seuraava komento:

 yarn add redux react-redux redux-thunk 

Tai kun käytät npm

 npm install redux react-redux redux-thunk 

Meidän on myös asennettava niiden tyypit kehitysriippuvuuksina, jotta TypeScript voi ymmärtää kirjastoja.

Joten, suoritetaan tämä komento uudelleen CLI: ssä.

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

Tai npm:

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

Loistava! Tällä askeleella eteenpäin voimme nyt luoda TypeScript-tyypit projektille seuraavassa osassa.

Luo tyypit

TypeScript-tyyppien avulla voit asettaa tyyppejä muuttujille, toimintoparametreille ja niin edelleen.

  • tyyppi. 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 

Tässä aloitetaan ilmoittamalla käyttöliittymä, IArticlejoka heijastaa tietyn artikkelin muotoa.

Sitten meillä on ArticleState, ArticleActionja DispatchTypese toimii tyyppeinä vastaavasti olioobjektille, toiminnan luojille ja Reduxin toimittamalle lähetystoiminnolle.

Meillä on nyt tarvittavat tyypit React Reduxin käytön aloittamiseen. Luodaan toimintotyypit.

Luo toimintotyypit

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

Tarvitsemme kaksi toimintatyyppiä Redux-myymälää varten. Yksi artikkeleiden lisäämiseen ja toinen poistamiseen.

Luo toiminnan luojat

  • 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) } } 

Tässä opetusohjelmassa simuloin HTTP-pyyntöä viivyttämällä sitä 0,5 sekunnin ajan. Mutta voit käyttää todellista palvelinta, jos haluat.

Tässä funktio addArticlelähettää toiminnon uuden artikkelin lisäämiseksi, ja menetelmä removeArticletekee päinvastoin. Poista siis argumentiksi syötetty objekti.

Luo vähennysventtiili

Pienennin on puhdas funktio, joka vastaanottaa tallennustilan ja toiminnon parametreina ja palauttaa sitten päivitetyn tilan.

  • myymälä / vähennysventtiili. 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", }, ], } 

Kuten voit nähdä täältä, julistamme alkutilaksi artikkeleita, joita näytetään sivun latautumisen yhteydessä. ArticleStateTilaobjektin on vastattava tyyppiä - muuten TypeScript heittää virheen.

  • myymälä / vähennysventtiili. 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:

sovelluksen esikatselu

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

Valmiin projektin löydät tältä CodeSandboxista.

Löydät muuta tällaista mahtavaa sisältöä blogistani tai seuraa minua Twitterissä saadaksesi ilmoituksen.

Kiitos lukemisesta.