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

✨ migrate to k-ramel #123

Merged
merged 21 commits into from Feb 17, 2018
Merged

✨ migrate to k-ramel #123

merged 21 commits into from Feb 17, 2018

Conversation

bpetetot
Copy link
Owner

@bpetetot bpetetot commented Feb 10, 2018

Closes #104

@fabienjuif
Copy link
Collaborator

How do you feel this migration right now ?

@bpetetot
Copy link
Owner Author

bpetetot commented Feb 11, 2018

I am doing the migration in several steps :

  • 1. apply createStore and inject of k-ramel (without refactoring) (836087d)
    works directly with hideRedux=false ❤️
  • 2. apply hideRedux=true and make it working (38818df)
  • 3. replace redux reducers by k-redux-factory
  • 4. replace saga by listeners progressively and refactor actions names (it's messy today)
  • 5. apply listeners closer to the screens

@@ -1,19 +1,20 @@
import { connect } from 'react-redux'
import { inject } from 'k-ramel/react'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am thinking about publishing x distincts packages:

  • k-ramel
  • @k-ramel/react
  • @k-ramel/driver-http
  • @k-ramel/...

What is your though ?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it's a good idea, but I think you should keep an unique github repository with sub-packages

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that is the idea :)

@@ -9,7 +9,7 @@ import MyTalks from './myTalks'
const mapStore = store => ({
loaded: store.ui.speaker.myTalks.isInitialized(),
talks: store.ui.speaker.myTalks.getAsArray(),
load: () => store.dispatch({ type: 'ON_LOAD_SPEAKER_TALKS' }),
load: () => store.dispatch({ type: '@@ui/ON_LOAD_SPEAKER_TALKS' }),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can dispatch('@@ui/ON_LOAD_SPEAKER_TALKS') now if you want :)

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OMG ! I forgot that. its fantastic !

@bpetetot
Copy link
Owner Author

@fabienjuif @guillaumecrespel

k-ramel migration finished and saga out !
About 1/3 of code deleted

Now I must do some tests to see if I have some regression, but the migration was not difficult and progressive.

@guillaumecrespel
Copy link

is it possible to use your example in our talk ?
image

@fabienjuif
Copy link
Collaborator

There still have some refactoring to do @bpetetot
I think about drivers.
You use a lot of dispatch in your reactions.

We have a custom driver (that we have to open source) for redux-form, it is like this:

import { setSubmitSucceeded, getFormValues, setSubmitFailed, startSubmit, stopSubmit, isSubmitting } from 'redux-form'

const asyncSubmit = (name, dispatch, getState) => async (http, ...options) => {
  dispatch(startSubmit(name))
  await http(...options)
  if (isSubmitting(name)(getState())) dispatch(stopSubmit)
}

export default ({ dispatch, getState }) => name => ({
  getFormValues: () => getFormValues(name, state => state.ui.form)(getState()),
  setSubmitFailed: (...fields) => dispatch(setSubmitFailed(name, ...fields)),
  setSubmitSucceeded: () => dispatch(setSubmitSucceeded(name)),
  startSubmit: () => dispatch(startSubmit(name)),
  stopSubmit: errors => dispatch(stopSubmit(name, errors)),
  asyncSubmit: (http, ...options) => asyncSubmit(name, dispatch, getState)(http, ...options),
})

And can be use like this for example:

export const login = reaction((action, store, { http, form }) => {
  // retrieve credentials from redux
  const signin = form('signin')
  const values = signin.getFormValues()
  // call API
  signin.asyncSubmit(
    http('AUTH')
    '/api/login',
    {
      method: 'POST',
      body: JSON.stringify(values),
      headers: { 'Content-Type': 'application/json' },
    },
  )
})

@bpetetot
Copy link
Owner Author

bpetetot commented Feb 14, 2018

Yeah ! that's great ! and yes I have a lot of refactoring to do :

  • use redux-form driver ❤️

  • find a way to manage data loading on routes and component mounting. Each time I have an URL with param eventId, I have to do a loader like that, I think I could factorize this code in a better way.

const mapStore = (store) => {
  const eventId = getRouterParam('eventId')(store.getState())
  const event = store.data.events.get(eventId)
  return {
    loaded: !!event,
    eventId,
    load: () => store.dispatch('@@ui/ON_LOAD_EVENT'),
  }
}
export default compose(
  forRoute.absolute('PROPOSALS'),
  inject(mapStore),
  loader,
)(Proposals)
  • maybe create a driver to have a simpliest use of the router in reaction :
 // replace
 const eventId = getRouterParam('eventId')(store)
 // by
 const eventId = router.getParam('eventId')

 // replace
 store.dispatch(push(`/organizer/event/${eventId}`))
 // by
 router.push(`/organizer/event/${eventId}`)
  • rename some action names, it's still messy in my mind sometimes

@fabienjuif
Copy link
Collaborator

For the second point, look at the new hoc listen.
Maybe we can dispatch an event in this hoc like @@krml/LISTEN_PLUGUED>${componentName}

And in the listeners you plug with listen hoc, you catch that ?

@bpetetot
Copy link
Owner Author

@guillaumecrespel yes you can ;)

const mapStore = (store) => {
const talkId = getRouterParam('talkId')(store.getState())
const talk = store.data.talks.get(talkId)
return {
loaded: !!talk,
form: FORM_NAME,
form: 'talk-edit',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are throwing away the optimisation with a string here I think.
This was better to make it a constant so the string reference is always the same and the shallowCompare works better

@@ -0,0 +1,25 @@
import {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should wait k-ramel driver before merging IMO

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I will wait for it ;)

store.dispatch(stopSubmit(FORM, { _error: error.message }))
throw error
}
export const createEvent = reaction(async (action, store, { form }) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is better !

// update event into database
updateForm.asyncSubmit(eventCrud.update, event)
// update event in store
store.data.events.update(event)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you want to await asyncSubmit ?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I'm an optimistic guy 😃

@@ -1,51 +1,30 @@
import { reaction } from 'k-ramel'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we agree, but this file should be attach with listen hoc no ?
And others of same types

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it will be an other refactoring step...

@fabienjuif
Copy link
Collaborator

❤️

@bpetetot bpetetot deleted the 104-migrate-to-k-ramel branch February 17, 2018 10:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants