Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Real world examples (including CRUD, advanced patterns, etc) #1353

Closed
EricSimons opened this issue Feb 2, 2016 · 45 comments
Closed

Real world examples (including CRUD, advanced patterns, etc) #1353

EricSimons opened this issue Feb 2, 2016 · 45 comments
Labels

Comments

@EricSimons
Copy link

Originally inspired by Dan's tweet.

TL;DR - We'd love to fund the creation/code review/pedagogy of a fully fledged Redux app covering real world use cases that would be hosted in this repo as well as a Thinkster.io course. The course's text & code would be open source (we're thinking CC & MIT, respectively) so this knowledge won't be locked behind a paywall.

Writing rich examples takes a lot of time and requires writeable API endpoints (amongst other things). However, it's something that I feel is really important to ensure devs have a good frame of reference when building out their applications. We also have a ton of our users asking for this sort of primer on Redux, and as such, we're happy to fund its creation.

Would love to hear any ideas ya'll have about this and lmk if you're interested in working on it!

@gaearon
Copy link
Contributor

gaearon commented Feb 2, 2016

I’d love to have an official CRUD example that handles:

  • Authentication
  • Normalization
  • Optimistic updates
  • Local editing
  • Entity relationships
  • Pagination

If you’d like to build a course around this, it is amazing. However I think it is important that the example itself is contributed to this repo so we can maintain it and keep it up to date with the latest changes. Therefore it should be consistent with the build system and conventions we use in the existing examples.

Does this make sense?

@sebastiandeutsch
Copy link

I'd also love to see where the people are fetching data from APIs.

@EricSimons
Copy link
Author

@gaearon the content/code will be open source, so that's no problem. We'd just ask for a link back to us somewhere on the page :) (edit - using existing build system/conventions is preferable for us as well)

@sebastiandeutsch can you elaborate a bit on this?

@vkarpov15
Copy link

A while back I started playing around with writing a password manager using react+redux, monogram, and eccrypto. Store passwords and share them all without ever sending them over the wire in an unencrypted form using ECIES. Never quite got around to really finishing it, but it could very well satisfy all the items in #1353 (comment). Does that sound interesting?

@gaearon
Copy link
Contributor

gaearon commented Feb 2, 2016

@vkarpov15

This does sound very interesting but I’m afraid it’s a little too domain specific. Most people will want to see a general CRUD example (lists of editable items that can link to either items, etc), and I’m afraid a crypto focus might make the example less approachable.

@mattiamanzati
Copy link

I'm a lot interested in local/offline editing with optimistic updates, I have some time but I am not so experienced with redux app, I only got a complex native app, but almost fully local/offline.
Maybe we could write a repo and work on it and incrementally discuss?
Also what about "modular" apps?
Just to share some ideas, i wrote down some ideas about How I think offline first app should be, give it a shot if you have time to spend in it! :)

jsforum/jsforum#7

@sompylasar
Copy link

Not sure how widespread is the problem and what's the target level of developers for this course, but I'd like to see somewhere on the net how to architect complex app components implemented in react+redux (like a multi-step form or wizard with state controlled by several reducers) so they are reusable as a whole in another app.

@gaearon
Copy link
Contributor

gaearon commented Feb 2, 2016

@sompylasar Please feel free to create an issue about this in React Redux repo. I’m happy to discuss approaches to reusing or isolating Redux-aware component there.

@vkarpov15
Copy link

If you're looking for a beginner-level crud example there's always todo-mvc and the army of "getting started with babel+redux+react+webpack" tutorials out there. I'm not sure there's much value to yet another one, I end up reading a couple new blog posts on the subject every week (but perhaps you could build an app that automatically generates these tutorials? :p ). I'd argue that a more intermediate level tutorial would be more worthwhile, and IMO learning about crypto could be an enticing side benefit.

@gaearon
Copy link
Contributor

gaearon commented Feb 2, 2016

I’m not looking for a beginner-level example, but the complex parts of CRUD (pagination, normalization, optimistic updates, relationships) should be the focus of the example.

@cshenoy
Copy link

cshenoy commented Feb 2, 2016

Would this be consuming a custom or an existing API? Or combination?

@gaearon
Copy link
Contributor

gaearon commented Feb 2, 2016

This is the hard question. I don’t know. Github API may be a good idea since it’s writeable and concepts are familiar to everybody. I know @ryanflorence worked on something similar.

@EricSimons
Copy link
Author

Definitely targeting intermediate-advanced devs with this; the beginner tuts have been saturated and rarely cover the (real world) harder topics Dan listed above.

I'm open to both custom and/or existing API - we'd be happy to host any custom APIs on our aws account. We also have a full blown API for a Medium.com clone that we're building out for a few other courses that we could use, backend source code would also be available for it as well should folks be curious. Happy to share details if that sounds interesting.

@cshenoy
Copy link

cshenoy commented Feb 2, 2016

@EricSimons I'd love to know more about the Medium clone.

@EricSimons
Copy link
Author

@cshenoy For sure. We're building a fullstack JS course that will have React/Redux as the frontend and Node as the backend. We'll have the backend API hosted independently for folks who don't want to run it locally, so it might be a good fit for teaching some of the more complex topics above. The feature set for the Medium clone includes the following:

  • Authentication (email/pass & oAuth, JWT)
  • CRUD for blog posts & comments on blog posts
  • Following users
  • Global feed of all blogs & a feed of the blogs of the users you follow
  • Tagging system
  • User profiles/editing profile info

ETA on the final codebase is by the end of this week, so I'll have more info around then. We've designed everything to be super modular, so adding additional features would be trivial.

@dan-weaver
Copy link

Timesheets (time trackers) really exercise a lot of complex aspects of flux/redux and crud. Pagination and cacheing are obvious needs as you scroll through days and weeks back and forth. There are also plenty of writeable APIs already existing. There's a lot more than just time tracking involved also. User management, project entities etc.

@jonathaningram
Copy link

I think this would be great. I've struggled with it a bit, especially the create part of it. E.g. suppose you have an ArticlePage component that creates new articles like this:

// shortened version

import { addArticle } from '../actions'

function doAddArticle(props, handleAdded, values, dispatch) {
  props.addArticle(values)
  .then(handleAdded)
}

class AddArticlePage extends Component {
  handleAdded = () => {
    this.props.pushState(null, '/articles/')
  };

  render() {
    return (
      <div>
        <ArticleForm submit={(values, dispatch) => doAddArticle(this.props, this.handleAdded, values, dispatch)} />
      </div>
    )
  }
}

function mapStateToProps(state) {
  return {}
}

export default connect(mapStateToProps, {
  pushState,
  addArticle
})(AddArticlePage)
  1. I'm not even sure if it's the "right" thing to do to chain off the resolved promise to do the redirecting.
  2. What if I want to get the ID from the newly created article and instead of redirecting to the index page, I want to redirect to the /articles/{id}/ page?
  3. What if my component wants the result of the async action? For me, this came up within my ArticleForm component with an image upload form field: I dispatch an action "addImage" and when the image has loaded I want to 1) show a preview of the uploaded image based on URL and 2) want to assign the URL to the form. But, I found it hard to figure out what was the best way to do this in Redux. The problem I found was that you need to be able map the newly added state/image to a prop in the form component, but 1) how do you get the newly added image and 2) what if there are 2 images uploading simultaneously, how do you get the right image URL for the right component?

Granted, I have only been Redux-ing for a few months so they might be silly issues, but as a beginner they definitely tripped me up and I still don't feel my solutions are the "right way".

@babsonmatt
Copy link

@jonathaningram have you looked at redux-thunk at all? As an alternative to what you're doing above, it would let you dispatch from within your action

@jonathaningram
Copy link

@babsonmatt yep I am using it already. I based the app off the real-world example which uses it. Maybe I'm not using it to it's full capabilities though.

@sompylasar
Copy link

@jonathaningram Thanks for your example. As was pointed out, you should move the redirect logic to the action creator's thunk, and dispatch the route update from there. There are more ways to manage side effects (the redirect is a side effect of the state transition caused by that action), like redux-saga or redux-side-effects. But I think the deep discussion is out of scope of this issue.

@jonathaningram
Copy link

@sompylasar thanks. Yep I don't want to sidetrack the issue but just wanted to share my "real world" experiences as a redux beginner which hopefully helps the new examples that arise from this issue.

@dan-weaver
Copy link

@EricSimons I'm interested in helping. I'm currently maintaining a CRUD app using nuclear-js and I think a lot of it's ideas would translate well to redux. Let me know if you want to brainstorm.

@masylum
Copy link

masylum commented Feb 3, 2016

I recently started a project for CRUD (over REST) state management. Coming from Marionette/Backbone I really missed REST conventions when started digging on React/Redux.

https://github.com/masylum/resting-ducks

I'm not sure wether the solution are examples. I think libraries work better for that. State management is almost always the same, at 2016 we shouldn't be writing CRUD code but focusing on our business logic.

@sebastiandeutsch
Copy link

@EricSimons I'm currently evaluating different options where to specify data needs and when to fetch data. One option would be to implement something Relayish - but I have the feeling that's a bit of a overkill. Something that I've made up for a project is to specify my loading needs in the routes with a loader attribute:

let routes = <Route path='/' component={Layout}>
  <IndexRoute component={BooksIndex} />
  <Route path='/book/new' component={BooksNew} />
  <Route path='/book/:id' component={BooksShow} loader={BooksLoader} />
  <Route path='/book/:id/edit' component={BooksEdit} loader={BooksLoader} />
</Route>;

The BooksLoader is a class that implements two functions:

  • needsToSyncStore(params, store) returns true if the store needs to be synched, else false
  • syncStore(params, store) will sync the store and return a promise

Here is a very basic example implementation that can be definitely replaced by something smarter (e.g. ImmutableJS / Map):

import _ from 'lodash';
import * as Actions from 'actions';
import API from 'api';

export default class BooksLoader {
  needsToSyncStore(params, store) {
    let books = store.getState().books;

    if(books) {
      const book = _.findWhere(books.collection, { isbn: params.id });
      if(book) {
        return false;
      }
    }

    return true;
  }

  syncStore(params, store) {
    let { dispatch } = store;
    let api = new API();

    let loadBooks = Actions.loadBooks();
    return loadBooks(dispatch, store.getState);
  };
}

The idea is that a loader only cares about the state that is provided by a route and the redux state tree which makes it easy to test.

The next piece is a store loader which is a react component heavily inspired by @ryanflorence AsyncProps (https://github.com/rackt/async-props) that can be used as RenderContext of ReactRouter: https://gist.github.com/sebastiandeutsch/e6148ca0741cc355248c

It is checking the routes of ReactRouter for loaders and the executing them. It also exposes the loading state via contexts. In action it would look like this:

<Provider store={store}>
  <Router
    history={browserHistory}
    render={(props) => (
      <StoreLoader {...props} store={store} />
    )}>
      {routes}
    </Router>
</Provider>

In a route component (these are special components that are direct children from the router) I can use the context like this:

export class BooksShow extends React.Component {
  static contextTypes = {
    storeIsSynchronized: React.PropTypes.bool
  };
  ...
  render() {
    const { book } = this.props;

    if(this.context.storeIsSynchronized) {
      /* display components */
    } else {
      /* display loading spinner */
    }
}

export default connect(
  (state, props) => {
    return {
      book: _.findWhere(state.books.collection, { isbn: props.params.id } )
    }
  },
  (dispatch) => ({
    actions: bindActionCreators(Actions, dispatch)
  })
)(BooksEdit);

@gaearon What do you think about these ideas?

@dan-weaver
Copy link

@sebastiandeutsch I like that approach. I too am experimenting with Async-Props your ideas here look really cool.

I imagined the example was supposed to be more general rather than being tailored around an abstraction for data fetching. I really like https://github.com/optimizely/nuclear-js/tree/master/examples/rest-api as a basic example of an easy way to set up stores and actions for Rest APIs.

I've extended it to support cacheing and even store ongoing requests in a store (so that if the request is made again the caller simply gets a deferred instead of reinitiating the xhr. A more robust example of what I'm talking about is here: https://github.com/jordangarcia/nuclear-api-module-example/tree/master/rest_api. And I've copied some of @jordangarcia's concepts with great success. I think the approaches here could work well with redux as well (accompanied by normalizr etc).

@EricSimons is the issue more about subject matter and finding good writable API's or are you looking for specific approaches?

@EricSimons
Copy link
Author

I'm mostly interested in subject matter (since worst case we can host our own writeable APIs for folks to use). Huge thanks to all of the commenters above btw, this discussion has been fantastic so far. Would love to hear more thoughts/ideas on what we should cover in these examples.

FYI @dan-weaver & others interested in working on this - feel free to shoot me a note [email protected]

@dferber90
Copy link
Contributor

In the Meteor world, there is one big open source example project which originated from a book about Meteor. This project is Telescope, which is a web application similar to Reddit or Hacker News. If Redux had a similar example, that would be great. Lot's of developers learned Meteor by following the book and building a smaller version of Telescope along with it. An application like Telescope would cover all the topics raised by Dan on an application most developers are already familiar with (because of Hacker News, Reddit, ..).

I started creating the basis for a similar application a few months back at webapp*. This project has the build process, css modules, authentication, a separate server for the API, MongoDB, server side rendering, GraphQL and more already set up (although some things may be a bit outdated, need some more work, or could be done better). It further has reducer splitting, something I believe no other example has. Big things it lacks is are good solutions to data fetching, optimistic updates, realtime data. Also, it's a bit outdated as 2 months seem like an eternity in how fast everything is progressing right now :)

If you want a starting point for creating the example for the course, maybe webapp could be an inspiration. And I'd love to see something similar to Telescope done in Redux.

*The knowhow folder contains some information about the architecture/decisions made.


Sidenote: Because I noticed Redux doesn't have a story for data fetching, I'm currently creating a system similar to Relay which integrates with Redux. That is the reason I haven't updated webapp for 2 months. In case I am successful with creating that system, I'll continue webapp with it.

@chrisui
Copy link

chrisui commented Feb 7, 2016

One issue faced is that Redux is so very low level and therefore pretty un-opinionated about how you actually build an application around it. I am therefore unsure whether we can simply maintain one example codebase to learn from since there are so many possible valid abstractions between redux and the final user interface. This is exemplified by some of the discussion in this thread where many different possibilities for data loading are presented with no clear winner - there is no one right way since application scales differ wildly.

For this reason coming up with "The Advanced TODOMVC of Redux" to a spec which requires all of the advanced features Dan has previously mentioned is desirable.

As we move forwards I believe we will begin to see more abstractions/libraries/frameworks around Redux which could use this advanced application as proof-of-concept. In fact over time this may be rebranded to be non-Redux specific.

On the API front I would love to see it follow some sort of standard (JSON-API Provides an excellent basis for denormalisation and describing relationships) and eventually have a GraphQL server in front of this.

As for how this is structured as a community I suspect we could have a core repo containing the application spec, server implementation/s as well as a list/comparison chart of all the current implementations.


On a side, but partially related, note from the specific topic here I think we would do well to prioritise this issue on clarifying the scope of Redux - emphasising the low level nature.

Ps. I have a "Real World Redux" talk coming up at React London soon (where I'll hopefully get time to explore the more advanced issues at hand) so look out for that :D

@mxstbr
Copy link
Contributor

mxstbr commented Feb 13, 2016

I'd be up for working on this, I think providing newcomers with an usable, commented and explained Redux application that's not a todo list is a great idea. Has any work on this started yet @EricSimons?

@ghost
Copy link

ghost commented Feb 13, 2016

There seem to be a lot of similar questions about how to reduce redux's boilerplate and build something real-world with it. I think I found a pretty good solution (among other things) which I wrote about here:

https://medium.com/@timbur/react-automatic-redux-providers-and-replicators-c4e35a39f1

TL;DR: You can create redux providers that automatically match themselves to your components based on their propTypes. All you really need is a components directory, a providers directory, and an optional but recommended themes directory. Everything is easily interchangeable, understandable, maintainable, extendable, and reusable. There's a lot more included with all that like hot reloading both client and server, server rendering, etc., etc., etc. I built an app from scratch based on the included boilerplate earlier today and it took about 10 minutes as opposed to the 1 hour it would usually take. :)

@barrystaes
Copy link

Speaking from experience as an early-react adopter i'd rather not use the Github API in an example.

  • Its authentication is overcomplicated for someone looking for something that "just works".
  • Its not suited to experiment. To avoid being destructive while doing API mutations, i would have to make a separate/throwaway Github account.

Instead please use a simple custom API. We dont want to be dependant on 3th parties, and enable anyone to run their own instance like my BottledAPI example (wip) in json-server.

This would also allow other rest backend implementations in Javascript, Java, C#, PHP, etc. This would help kickstart development, as its pretty turn-key.

@ghost
Copy link

ghost commented Feb 21, 2016

BTW within the link in my comment above, there's details on how to build a blog app. I am planning on adding user auth and all that within the next week.

@gustavohenrique
Copy link

Hi guys! I'm studying ReactJS and I developed a version of my personal URL shortener using React + Redux. My example uses Gulp + Browserify + Babelify for frontend development. I wrote unit tests using Mocha and Enzyme for components and actions. This example has also:

  • Create, Read and Update operations
  • Authentication with Json Web Token
  • Pagination
  • Tags
  • CORS

There are some bugs in the interface and usability. But it's working =)
Maybe someone can use it as base for an real world example.

Demo: https://gustavohenrique.github.io/gh1
Source: https://github.com/gustavohenrique/gh1

I accept suggestions about how to improve this example. Thanks!

@SebastienDaniel
Copy link

Little late to the party, but I've just launched a full-fledged management web application that is built on Redux.

We use redux-thunk for async jobs, and use redux-ignore which provided a surprising improvement (on mobile), just by filtering our top-level reducers.
The web app is 100% responsive, so it's easy to use/test on mobile.

We manage optimistic updates by "rollingback" the previous action. The affected reducers know how to track their way back to their previous state, so it's quite isolated and efficient.

Anyway, here are the links http://www.handy-erp.com/en/
Just create an account and knock yourselves out.

@gustavohenrique
Copy link

@SebastienDaniel Congrats! it's a beautiful website. Did you put the redux part in any public repository?

@SebastienDaniel
Copy link

Thank you @gustavohenrique
Unfortunately no, the source is not in a public repo. However, I'm quite open to using the source to help cover any questions or maybe build demos to help out the community.

@pennyandsean
Copy link

I'd really like to see examples of modularity. If you are building an app with a huge amount of functionality, you really go looking for a way of building single responsibility modules. Better for teams, better for maintainability.

@gggin
Copy link

gggin commented Apr 6, 2016

First, Thank you for share code!@gustavohenrique
Other things:
I think may be a user list? login? register...
redux need these examples!

@MarkMurphy
Copy link

I agree with @gggin and @EricSimons a fully fledged production ready version of these features would be amazing:

Authentication (email/pass & oAuth, JWT)
CRUD for blog posts & comments on blog posts
Following users
Global feed of all blogs & a feed of the blogs of the users you follow
Tagging system
User profiles/editing profile info

In addition to this, a basic roles or permissions system would be great. Something equivalent to GitHub's teams or Trello's members

@peterpme
Copy link

Hey everybody,

I've been working on a loose proposal for a robust redux crud api just based my experience over the past couple of weeks:

https://github.com/ppiekarczyk/redux-crud-api-middleware/blob/master/README.md

Any feedback would be appreciative. Thanks!

I would be willing to take the application I'm building now and converting it to a open source example project as well.

@EricSimons
Copy link
Author

Hey all -- we're happy to announce that the example codebase is almost ready for review. It's super thorough and covers most of the real world use cases we've talked about in this thread (auth, CRUD, pagination, etc). @vkarpov15 has a few things to finish up on it, but it should be ready sometime early next week.

We'd love your help reviewing the codebase. I know @gaearon mentioned he'd be willing to take a look a few months back, and any & all feedback from the community here would be excellent. We'll be using this repo for the initial codebase while we review & iterate, then syndicate the final to the official redux repo once ready. Feel free to star/watch, and I'll also post an update in this thread once the codebase is online & ready for review.

Happy to answer any q's & thank you to everyone here for the excellent discussion!

@markerikson
Copy link
Contributor

Sounds good. Be sure to add a mention and link in the related Redux FAQ question when it's ready.

@EricSimons
Copy link
Author

As promised, the codebase is ready for review over at https://github.com/GoThinkster/redux-review, would love to hear everyone's feedback. Issues & PRs welcome!

@hhsadiq
Copy link

hhsadiq commented Feb 4, 2017

Hey guys, thanks a lot for awesome discussion and putting down a great real world example..

Just to add to list of such examples, I came across this example https://github.com/andrewngu/sound-redux, working demo deployed to https://soundredux.io/. It seems that it also qualifies to criteria which @gaearon was talking about. But I am not sure, so would be helpful if someone can give feedback. If it does qualify, it will be good addition to list. Plus its actively maintained for last year and a half.

And finally, special thanks to @EricSimons for awesome real world example.

@markerikson
Copy link
Contributor

I did actually add an FAQ entry that points to a number of real-world React and Redux apps, at http://redux.js.org/docs/faq/Miscellaneous.html#miscellaneous-real-projects . (Actually, I know I've seen that Sound-Redux app before, but I don't think I added it to my list. I'll have to do that.)

I'm going to go ahead and close this issue on the grounds that there no longer seems to be an immediate need to add a larger example directly to the Redux repo, given the number of "for-real" apps out there that we can point to. If someone would like to actively contribute a specific example to the repo, say something and we can reopen this.

And yes, thanks to all who have contributed discussion and examples!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests