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

Delayed file upload... where to put File objects? #1851

Closed
olalonde opened this issue Jul 18, 2016 · 3 comments
Closed

Delayed file upload... where to put File objects? #1851

olalonde opened this issue Jul 18, 2016 · 3 comments

Comments

@olalonde
Copy link

olalonde commented Jul 18, 2016

I'm looking for a suggestion on handling file uploads. I have a landing page where users can drag and drop a file and are then prompted to sign up before the file upload begins. I need to hold the dragged file object somewhere but since Redux state is only supposed to hold plain JS objects, I'm not sure where to put that file object. I could hold it in some React state/prop but I then have to make sure it is eventually passed to the right component, etc.

@olalonde
Copy link
Author

One possible solution would be to listen to the store for state changes using store.subscribe though I'm not sure how to get access to store.subscribe using connect(...). Maybe this.context.store.subscribe()?

@johanneslumpe
Copy link
Contributor

@olalonde The recommendation that the state should be serializable is a soft one - it's not set it stone. It mainly exists in order to facilitate easy server-side rendering and state snapshotting because you need to be able to serialize your state in order to hydrate it on the client or send it somewhere. As this is purely done on the client it might not be too bad to just go ahead and store that file object short-term for further processing.

And even if you then serialize your state - a File descriptor will be serialize to an object object, so you won't get a serialization error.

@olalonde
Copy link
Author

olalonde commented Jul 18, 2016

Thanks. I ended up wrapping my upload action creator with the following function:

waitIntroMessageShowedActionCreator.js

// delays execution of `fn` until `state.session.user.ui.introMessageShowed === true`

export const initWaitIntroMessageShowed = ({ getState, subscribe }) => (fn) => () => (
  new Promise((resolve, reject) => {
    const handleChange = () => {
      const state = getState()
      if (!state.session.user.ui) return null
      if (!state.session.user.ui.introMessageShowed) return null
      /* eslint-disable no-use-before-define */
      unsubscribe()
      return Promise
        .resolve()
        .then(() => fn())
        .catch(reject)
        .then(resolve)
    }
    const unsubscribe = subscribe(handleChange)
    handleChange()
  })
)

and in my component:

class DragDropSignup extends Component {
  constructor(props) {
    super(props)
    const waitIntroMessageShowed = initWaitIntroMessageShowed(this.props.store)
    this.onSignupSuccess = waitIntroMessageShowed(this.onSignupSuccess.bind(this))
  }
 // ...
}
// ...

// pass store object as prop
const connectStore = () => (WrappedComponent) => {
  const ConnectStore = (props, context) => (
    <WrappedComponent store={context.store} {...props} />
  )
  ConnectStore.contextTypes = { store: React.PropTypes.object }
  return ConnectStore
}

export default connectStore()(connect()(DragDropSignup))

Posting here in case it's useful to someone

@reduxjs reduxjs deleted a comment from cyrilchapon Mar 29, 2018
brandoncroberts pushed a commit to brandoncroberts/redux that referenced this issue Oct 13, 2023
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

No branches or pull requests

2 participants