Kaip naudoti „Redux“ „React TypeScript“ programoje

„Redux“ yra nuspėjamas „JavaScript“ programų būsenos konteineris. Tai populiari biblioteka, skirta valdyti būseną „React“ programose.

„Redux“ gali pasiūlyti geresnę kūrėjo patirtį, kai ją naudojate kartu su „TypeScript“. „TypeScript“ yra „JavaScript“ viršutinis rinkinys, kuris tipo patikrina kodą, kad jis būtų tvirtas ir suprantamas.

Šiame vadove aš jums parodysiu, kaip naudoti „Redux“ jūsų „React TypeScript“ projekte, sukurdami programą, leidžiančią pridėti, ištrinti ir rodyti straipsnius.

Pasinerkime.

  • Būtinos sąlygos
  • Nustatymas
  • Sukurkite tipus
  • Sukurkite veiksmų tipus
  • Sukurkite veiksmo kūrėjus
  • Sukurkite reduktorių
  • Sukurkite parduotuvę
  • Sukurkite komponentus

Būtinos sąlygos

Šioje pamokoje daroma prielaida, kad turite bent pagrindinį supratimą apie „React“, „Redux“ ir „TypeScript“.

Taigi, jei nesate susipažinę su šiomis technologijomis, pirmiausia pabandykite perskaityti šį „TypeScript“ praktinį vadovą arba šią „React Redux“ mokymo programą. Priešingu atveju pradėkime.

Projekto rengimas

Norėdami naudoti „Redux“ ir „TypeScript“, turime sukurti naują „React“ programą.

Norėdami tai padaryti, atidarykite CLI (komandų eilutės sąsaja) ir vykdykite šią komandą:

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

Tada struktūrizuokime projektą taip:

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

Projekto failų struktūra yra gana paprasta. Tačiau reikia atkreipti dėmesį į du dalykus:

  • storeAplankas, kuriame yra failai, susiję reaguoti Redux.
  • type.d.tsFailą, kuris turi mašinėle tipų, kurie gali būti naudojami dabar kitus failus be importuoti.

Be to, dabar mes galime įdiegti „Redux“ ir sukurti pirmąją savo parduotuvę.

Taigi, atidarykime projektą ir vykdykime šią komandą:

 yarn add redux react-redux redux-thunk 

Arba naudojant npm

 npm install redux react-redux redux-thunk 

Mes taip pat turime įdiegti jų tipus kaip kūrimo priklausomybes, kad „TypeScript“ suprastų bibliotekas.

Taigi, vykdykime šią komandą dar kartą CLI.

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

Arba npm:

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

Puiku! Žengdami šį žingsnį į priekį, kitame skyriuje dabar galime sukurti projekto „TypeScript“ tipus.

Sukurkite tipus

„TypeScript“ tipai leidžia nustatyti kintamųjų, funkcijų parametrų ir kt. Tipus.

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

Čia mes pradedame deklaruodami sąsają, IArticlekuri atspindi konkretaus straipsnio formą.

Tada mes turime ArticleState, ArticleActionir, DispatchTypekurie bus naudojami kaip tipai atitinkamai valstybės objektui, veiksmo kūrėjams ir išsiuntimo funkcijai, kurią teikia Redux.

Be to, dabar turime reikiamų tipų, kad galėtume pradėti naudoti „React Redux“. Sukurkime veiksmo tipus.

Sukurkite veiksmų tipus

  • parduotuvė / actionTypes.ts
export const ADD_ARTICLE = "ADD_ARTICLE" export const REMOVE_ARTICLE = "REMOVE_ARTICLE" 

„Redux“ parduotuvėje mums reikia dviejų tipų veiksmų. Vienas skirtas straipsniams pridėti, kitas - ištrinti.

Sukurkite veiksmo kūrėjus

  • parduotuvė / 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) } } 

Šioje pamokoje imituosiu HTTP užklausą atidėdamas ją 0,5 sekundės. Bet jei norite, drąsiai naudokitės tikru serveriu.

Čia funkcija addArticleišsiųs naują straipsnį įtraukiantį veiksmą, o metodas removeArticleatliks priešingai. Taigi ištrinkite objektą, pateiktą kaip argumentą.

Sukurkite reduktorių

Reduktorius yra gryna funkcija, kuri gauna parduotuvės būseną ir veiksmą kaip parametrus, tada grąžina atnaujintą būseną.

  • parduotuvė / reduktorius.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", }, ], } 

Kaip matote čia, mes skelbiame pradinę būseną, kad kai kurie straipsniai būtų rodomi, kai puslapis įkeliamas. ArticleStateBūsenos objektas turi atitikti tipą - kitaip „TypeScript“ sukels klaidą.

  • parduotuvė / reduktorius.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:

programos peržiūra

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

Parengtą projektą rasite šioje „CodeSandbox“.

Kito panašaus turinio galite rasti mano tinklaraštyje arba sekti mane „Twitter“, kad gautumėte pranešimą.

Ačiū, kad skaitėte.