/ReduxABox

A counter application implemented at www.CoderSchool.vn with ES6, React & Redux.

Primary LanguageJavaScript

CoderSchool FTW

Video tutorial

React, Redux, & ReduxABox Created with love by: Loi Tran

Try it out here

A fun box app using fundamental elements of ES6, React, & Redux.

In the course of building this we took several different approaches in terms of architecture and styling. This process gave us a greater appreciation of the problems which arise when many React components care about the same piece of state within an application.

  • Nesting components deeply leads to problems such as prop drilling
  • Prop drilling makes our components brittle to refactoring
  • Leaving state in multiple component is difficult to reason about

After we encountered these problems, we explored different solutions using Redux. We also experimented with a new API from React called hooks. These things allowed us to accomplish the following

  • Get data where it's needed without the bloat of prop drilling
  • Dispatch actions that effected global state from any component regardless of placement hierarchy
  • Identify expectations on our state through initial state in our store definition
  • Have a central source of truth regarding the state of our application, our store
  • Refactored our components to all be stateless, making them easier to reason about and understand
  • Used hooks to remove component level state entirely

Questions or Comments?

Feel free to make a pull request on solutions you think might be better and why. Specifically,

  1. Why is passing props to components with this component a good or bad idea?
const mapStateToProps = state => ({ ...state })
  1. Could we come up with a better way to use hooks in ./src/components/counter than useInterval?
import { useEffect, useRef } from 'react'

export const useInterval = (callback, delay) => {
  const savedCallback = useRef()

  useEffect(() => {
    savedCallback.current = callback
  }, [callback])

  useEffect(() => {
    function tick() {
      savedCallback.current()
    }
    if (delay !== null) {
      let id = setInterval(tick, delay)
      return () => clearInterval(id)
    }
  }, [delay])
}

License

Copyright [2019] [Loi Tran]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.