Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Brittney Postma
Brittney Postma

Posted on • Edited on • Originally published atconsole-logs.netlify.app

     

Explain Redux like I'm 5!

TLDR: Redux is a state management library that you can add to projects to help keep it organized. Here's some links:Redux.js.org,github repo, or checkout theCode Sandbox

Hi, I'm Brittney and I'm an instructor over atZTM Academy and the owner, designer, and developer atbDesigned. You can find more dev notes by me atConsole Logs.

Redux Logo


What is Redux?

     Redux is a tool that helps manage thestate of an application. Think of state as a box where we keep all of our toys. To play with our toys, we need to keep them organized so we can find them. Redux keeps your state organized and in one place. It also, keeps our things protected so they are harder to break. A lot of developers tend to think that Redux can only be used with React, another JavaScript library, but it can actually be ran alongside anyview library. Redux has a small weight of only 2kb and a large group of people that are constantly improving and adding things to it.


Redux Flow

Redux Flux Pattern

     Redux follows a unidirectional or one direction flow of data. It starts in theview, the item on a screen that a user sees when visiting your application. If a user clicks a button or types something in, we expect something to happen. This is called anaction and when an action happens, we need to make sure to change what is displayed to the user. To do this, Redux has a few steps it goes through. It starts when the user does an action in our application. That action isdispatched, that's just a fancy word for sent, through areducer function. A reducer simply condenses multiple things that could be happening into one final object to send back to the user. It needs to be apure function, every time you input the same thing, you should always get the same result returned. The reducer then hands that new condensed object back to thestore. The store is the container, our box, which holds the state. It then updates the state and gives it to the view to update. Now the user is seeing what they expect on the screen!

Why Redux?

Here are a few reasons you may want to add Redux to your project.

  • Good for managing large state.
  • Useful for sharing data between components.
  • Predictable state management.

Redux does these 3 things really well, by using these 3 principles:

  • 1. Having a single source of truth, a single large object that describes the entire state of the application.
  • 2. State is read only or immutable, each action creates a new version of state.
  • 3. Only changes state using pure functions, functions that given the same input always have the same output.

Getting Started With Redux

     Open a terminal to the directory of your application. To install Redux you can typenpm i redux if you are using npm oryarn add redux if you use yarn. If you are in aReact application, there is a separate package calledReact Redux that needs to be installed as well. To install React Redux you would typenpm i react-redux for npm oryarn add react-redux for yarn. Actually, there is a template of create-react-app that includes Redux. To start a new application with both React and Redux runnpx create-react-app my-app-name --template redux.

Setting Up React Redux

     If you have a project running on React that you want to add Redux to, there is some setup involved to convert your app over. You need to have added both theredux andreact-redux packages to your app. React Redux has a<Provider /> component, which allows the app to access the Redux store. You go into yoursrc/index.js file and around your<App /> component, you wrap the Provider component.

importReactfrom"react";importReactDOMfrom"react-dom";import{Provider}from"react-redux";importstorefrom"./redux/store";importConnectfrom"./Connect";constrootElement=document.getElementById("root");ReactDOM.render(<Providerstore={store}><Connect/></Provider>,rootElement);
Enter fullscreen modeExit fullscreen mode

     Now we haven't actually created our store yet, so lets do that next. Everyone seems to have their own folder structure that they like when creating an application, this is just one way of setting up your files. If you are more comfortable with your understanding of importing and exporting files, feel free to find the way that works best for you. In yoursrc folder inside your React application create a new folder called redux and inside of that createstore.js. Inside of store.js, is where we will create our Redux store and connect it with the reducers. We need to import createStore and applyMiddleware from Redux, our rootReducer that we have not created yet, and some middleWare packages to handle the async functions. We also need to installredux-thunk andredux-logger into our app. Usenpm i redux-thunk redux-logger for npm andyarn add redux-thunk redux-logger for yarn. The createStore function from Redux takes 3 optional arguments.

  • 1.reducer - A function that reduces any actions into 1 new state tree and returns the next state object.
  • 2.[preloadedState] - The initial or default state.
  • 3.[enhancer] - Optionally enhance the store with middleware or other 3rd party capabilities. Redux only comes with 1 enhancer, applyMiddleware().In this app, our initial state is going to be created inside the reducers file, so we do not have a preloadedState.
import{createStore,applyMiddleware}from'redux'// middleware for async reducersimportthunkMiddlewarefrom"redux-thunk";import{createLogger}from"redux-logger";// reducer file we have not created yetimport{rootReducer}from'./reducers.js'constlogger=createLogger();// from redux call createStore(reducer, [preloadedState], [enhancer])conststore=createStore(rootReducer,applyMiddleware(thunkMiddleware,logger));exportdefaultstore
Enter fullscreen modeExit fullscreen mode

     Now that we have created our store, we will create our actions objects. Create a new file inside theredux folder calledactions.js. As your app grows, this is where you may opt to create a folder with a separate file for each different action. As this is a smaller app, I am putting them into 1 actions.js file. Each action will take in the event that happened and a copy of the current state. It then updates thepayload or data and returns an updated copy of the state. We also need to create a file calledconstants.js to keep track of all of our type constants and import them into our actions.js file. The constants.js file is optional, it is a common practice in larger applications to hold all of the constant names of the action types.

// constants.jsexportconstCHANGE_SEARCHFIELD='CHANGE_SEARCHFIELD';exportconstREQUEST_ROBOTS_PENDING='REQUEST_ROBOTS_PENDING';exportconstREQUEST_ROBOTS_SUCCESS='REQUEST_ROBOTS_SUCCESS';exportconstREQUEST_ROBOTS_FAILED='REQUEST_ROBOTS_FAILED';
Enter fullscreen modeExit fullscreen mode
// actions.jsimport{CHANGE_SEARCHFIELD,REQUEST_ROBOTS_PENDING,REQUEST_ROBOTS_SUCCESS,REQUEST_ROBOTS_FAILED}from'./constants'exportconstsetSearchField=(text)=>({type:CHANGE_SEARCHFIELD,payload:text})exportconstrequestRobots=()=>(dispatch)=>{dispatch({type:REQUEST_ROBOTS_PENDING})constapiCall=(link)=>fetch(link).then(response=>response.json())apiCall('https://jsonplaceholder.typicode.com/users').then(data=>dispatch({type:REQUEST_ROBOTS_SUCCESS,payload:data})).catch(error=>dispatch({type:REQUEST_ROBOTS_FAILED,payload:error}))}
Enter fullscreen modeExit fullscreen mode

     Now we need to create ourreducers. Here, we probably should go ahead and create a new folder calledreducers inside the redux folder. Then create a file for each action reducer. I've createdposts.js,comments.js, androotReducer.js, which will combine all of our reducer functions into one function. Now we need to write our reducer functions. In posts.js, we will take our old state in and create an updated version of it, with the likes incremented by 1. In comments.js,

import{CHANGE_SEARCHFIELD,REQUEST_ROBOTS_PENDING,REQUEST_ROBOTS_SUCCESS,REQUEST_ROBOTS_FAILED}from"./constants";import{combineReducers}from"redux";constinitialStateSearch={searchField:""};exportconstsearchRobots=(state=initialStateSearch,action={})=>{switch(action.type){caseCHANGE_SEARCHFIELD:returnObject.assign({},state,{searchField:action.payload});default:returnstate;}};constinitialStateRobots={robots:[],isPending:true};exportconstrequestRobots=(state=initialStateRobots,action={})=>{switch(action.type){caseREQUEST_ROBOTS_PENDING:returnObject.assign({},state,{isPending:true});caseREQUEST_ROBOTS_SUCCESS:returnObject.assign({},state,{robots:action.payload,isPending:false});caseREQUEST_ROBOTS_FAILED:returnObject.assign({},state,{error:action.payload});default:returnstate;}};// take the 2 reducer functions and combine into 1exportconstrootReducer=combineReducers({requestRobots,searchRobots});
Enter fullscreen modeExit fullscreen mode

UPDATED: Connect the App

     To use the recommendedHooks API I have converted the App Component from a Class to a functional component and used hooks to connect the app. I have left the old way explained below and have commented it out in theCode Sandbox so you can see both ways.

     To connect our app using hooks, we need to go intosrc/App.js. First, we need to import the hooks we need to use.

  • useEffect - a method from react.
  • useDispatch - a method from react-redux.
  • useSelector - a method from react-redux.

The useEffect hook is needed to replace our componentDidMount function to load the robots. The useDispatch and useSelector from react-redux will replace the mapStateToProps and mapDispatchToProps functions in the Connect Component.

importReact,{useEffect}from"react";import{useDispatch,useSelector}from"react-redux";import{setSearchField,requestRobots}from"./redux/actions";import"./styles.css";// componentsimportCardListfrom"./components/CardList";importSearchBoxfrom"./components/SearchBox";importErrorBoundaryfrom"./components/ErrorBoundary";constApp=()=>{// replaces mapDispatchToPropsconstsearchField=useSelector(state=>state.searchRobots.searchField);constrobots=useSelector(state=>state.requestRobots.robots);constisPending=useSelector(state=>state.requestRobots.isPending);constfilteredRobots=robots.filter(robot=>{returnrobot.name.toLowerCase().includes(searchField.toLowerCase());});// replaces mapDispatchToPropsconstdispatch=useDispatch();constonSearchChange=e=>dispatch(setSearchField(e.target.value));useEffect(()=>{dispatch(requestRobots());},[dispatch]);return(<divclassName="body"><divclassName="stickyHeader"><h1className="f1">RoboFriends</h1><SearchBoxsearchChange={onSearchChange}/></div>{isPending?(<h1>Loading</h1>):(<ErrorBoundary><CardListrobots={filteredRobots}/></ErrorBoundary>)}</div>);};
Enter fullscreen modeExit fullscreen mode

OLD WAY: Connect the App

     The last thing we have left to do is connect our app to the store. In oursrc folder create a new component calledConnect.js. In Connect.js, we need to importconnect from react-redux and set up 2 functions:mapStateToProps andmapDispatchToProps. In mapStateToProps, we are giving access to the state or store to all the children components. In mapDispatchToProps, we are sending the events to the correct actions.

import{connect}from"react-redux";import{setSearchField,requestRobots}from"./redux/actions";importAppfrom"./App";constmapStateToProps=state=>({searchField:state.searchRobots.searchField,robots:state.requestRobots.robots,isPending:state.requestRobots.isPending});constmapDispatchToProps=dispatch=>({onSearchChange:event=>dispatch(setSearchField(event.target.value)),onRequestRobots:()=>dispatch(requestRobots())});// we take the 2 functions and connect them to our App componentconstConnect=connect(mapStateToProps,mapDispatchToProps)(App);exportdefaultConnect;
Enter fullscreen modeExit fullscreen mode

Finally, our app is fully connected to Redux! This is our final folder structure.

-public-src  -components    -Card.js    -CardList.js    -ErrorBoundary.js    -SearchBox.js    -component-styles.css  -redux    -actions.js    -constants.js    -reducers.js    -store.js  App.js  Connect.js  index.js  styles.csspackage.json
Enter fullscreen modeExit fullscreen mode

     You can find the code for the rest of the componentshere or checkout theCode Sandbox. Thanks for joining me and please remember to like the article if it helped you!

Top comments(12)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
markerikson profile image
Mark Erikson
Collector of interesting links. Answerer of questions. Writer of very long posts. Redux maintainer.
  • Joined

Hi, I'm a Redux maintainer. Please check out our new official Redux Toolkit package. It includes utilities to simplify several common Redux use cases, including store setup, defining reducers, immutable update logic, and even creating entire "slices" of state at once:

redux-toolkit.js.org

Also, whileconnect still works fine, we're now recommending that folks useour React-Redux hooks API as the default.

CollapseExpand
 
brittneypostma profile image
Brittney Postma
🌊 brittneypostma.com☕ buymeacoffee.com/brittneypostma😻 codingcat.dev🖊 theconsolelogs.com👩‍🏫 ZTM Academy🎈 redbubble.com/people/bDesigned/shop✨🌈
  • Email
  • Location
    US
  • Education
    Self Taught
  • Work
    Developer Experience Engineer @Netlify
  • Joined

Thank you, I'm going to try and convert it over and will update the article!

CollapseExpand
 
brittneypostma profile image
Brittney Postma
🌊 brittneypostma.com☕ buymeacoffee.com/brittneypostma😻 codingcat.dev🖊 theconsolelogs.com👩‍🏫 ZTM Academy🎈 redbubble.com/people/bDesigned/shop✨🌈
  • Email
  • Location
    US
  • Education
    Self Taught
  • Work
    Developer Experience Engineer @Netlify
  • Joined

I updated the article and the app if you wanted to take a second look. Thank you for your input!

CollapseExpand
 
omawhite profile image
Omar White
Hi my name is Omar, I’m a software engineer that specializes in creating great front end experiences, primarily using react. When I’m not engineering I like to game and make music.
  • Location
    Bloomington, IN
  • Education
    Indiana University
  • Pronouns
    He,Him,His
  • Work
    Senior Software Engineer at CVS Health
  • Joined

Hey Mark, can you elaborate on why you’re recommending the react-redux hooks as the default. What are the pro’s of that approach as opposed to wrapping components in connect.

CollapseExpand
 
markerikson profile image
Mark Erikson
Collector of interesting links. Answerer of questions. Writer of very long posts. Redux maintainer.
  • Joined

connect still works fine, and we're going to continue maintaining and supporting it indefinitely.

But,useSelector anduseDispatch are shorter and easier to work with in many cases, and they definitely work better with TypeScript. There's less indirection, less code, and it's more obvious what's happening.

Hooks in general (and especially React-Redux hooks) do bring up a different set of tradeoffs, which I talked about in my postThoughts on React Hooks, Redux, and Separation of Concerns and myReactBoston 2019 talk on "Hooks, HOCs, and Tradeoffs". I'd encourage you to go through those.

Thread Thread
 
omawhite profile image
Omar White
Hi my name is Omar, I’m a software engineer that specializes in creating great front end experiences, primarily using react. When I’m not engineering I like to game and make music.
  • Location
    Bloomington, IN
  • Education
    Indiana University
  • Pronouns
    He,Him,His
  • Work
    Senior Software Engineer at CVS Health
  • Joined

Thanks for the links, that’s exactly what I was looking for. My team and I have been trying to understand the trade offs.

CollapseExpand
 
abahari profile image
Aissam BAHARI
  • Joined

Great Writing, it will be better to use react Hooksreact-redux.js.org/api/hooks to avoid using connect ...

CollapseExpand
 
brittneypostma profile image
Brittney Postma
🌊 brittneypostma.com☕ buymeacoffee.com/brittneypostma😻 codingcat.dev🖊 theconsolelogs.com👩‍🏫 ZTM Academy🎈 redbubble.com/people/bDesigned/shop✨🌈
  • Email
  • Location
    US
  • Education
    Self Taught
  • Work
    Developer Experience Engineer @Netlify
  • Joined

Thank you, I'm going to try and convert it over and will update the article!

CollapseExpand
 
brittneypostma profile image
Brittney Postma
🌊 brittneypostma.com☕ buymeacoffee.com/brittneypostma😻 codingcat.dev🖊 theconsolelogs.com👩‍🏫 ZTM Academy🎈 redbubble.com/people/bDesigned/shop✨🌈
  • Email
  • Location
    US
  • Education
    Self Taught
  • Work
    Developer Experience Engineer @Netlify
  • Joined

I updated the article and the app if you wanted to take a second look. Thank you for your input!

CollapseExpand
 
sharmakushal profile image
Kushal sharma
I'm Kushal Sharma from India, I am a Frontend Developer and I like the Javascript and react
  • Location
    Punjab, India 🇮🇳
  • Education
    MCA
  • Work
    Full-stack Developer
  • Joined

Awesome post buddy. It helps me to clear mine some doubts regarding redux

CollapseExpand
 
brittneypostma profile image
Brittney Postma
🌊 brittneypostma.com☕ buymeacoffee.com/brittneypostma😻 codingcat.dev🖊 theconsolelogs.com👩‍🏫 ZTM Academy🎈 redbubble.com/people/bDesigned/shop✨🌈
  • Email
  • Location
    US
  • Education
    Self Taught
  • Work
    Developer Experience Engineer @Netlify
  • Joined

Thank you so much, glad it helped.

CollapseExpand
 
lewismcampbell profile image
Lewis Campbell
  • Location
    Manchester, United Kingdom
  • Work
    Founder & Software Developer at Geekotist
  • Joined

Great write up, helped with my understanding of it. I know it's something I need to implement at some point properly

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

🌊 brittneypostma.com☕ buymeacoffee.com/brittneypostma😻 codingcat.dev🖊 theconsolelogs.com👩‍🏫 ZTM Academy🎈 redbubble.com/people/bDesigned/shop✨🌈
  • Location
    US
  • Education
    Self Taught
  • Work
    Developer Experience Engineer @Netlify
  • Joined

More fromBrittney Postma

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp