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

Store properties undefined on "first render" #14

Open
Mathieu-R opened this issue Feb 6, 2018 · 3 comments
Open

Store properties undefined on "first render" #14

Mathieu-R opened this issue Feb 6, 2018 · 3 comments

Comments

@Mathieu-R
Copy link

Mathieu-R commented Feb 6, 2018

For a reason that I do not know, my store is undefined on "first render".

In that capture of devtools console, I log a property of my store.
It is first undefined then HMR comes and then the property is defined.

image

import { Component } from 'preact';
import { connect } from 'unistore/preact';

@connect(['toast'])
class Toast extends Component {
  render ({toast}, {}) {
    console.log(toast);
    return (
      <div class="toast-container">
        <div class="toast">
          {/*toast.messages.map((message, index) => (
            <p class="toast--content" key={index}>{message}</p>
          ))*/}
        </div>
      </div>
    )
  }
}

export default Toast;
// store/worker.js
import createStore from 'stockroom/worker';
import idbKeyVal from 'idb-keyval';
import Constants from '../constants';

const store = createStore({
  user: {
    userId: '',
    email: '',
    avatar: ''
  },
  toast: {
    messages: [],
    show: false
  }
});

// globally available actions
store.registerActions(store => ({
  toasting ({toast}, messages) {
    return {
      toast: {
        messages,
        show: true
      }
    };
  }
}));
// index.js
import createStore from 'stockroom';
import storeWorker from 'workerize-loader!./store/worker';
import { Provider, connect } from 'unistore/preact';
import devtools from 'unistore/devtools';

const production = process.env.NODE_ENV === 'production';
const store = production ? createStore(storeWorker()) : devtools(createStore(storeWorker()));

import './style/index.scss';
import App from './components/app';

export default () => (
  <Provider store={store}>
    <App />
  </Provider>
);

I don't have that problem when I only use unistore without stockroom.

@Mathieu-R Mathieu-R changed the title Store undefined on first render Store properties undefined on "first render" Feb 6, 2018
@Kanaye
Copy link
Contributor

Kanaye commented Feb 12, 2018

That 's kinda expected, because stockroom initializes the store asynchronous from within the webworker, the state won't be available on first render.

Maybe it would be worth to add a initialized property to the store and maybe a component that only renders it 's children after the store received the initial state.

What do you think @developit ?

@developit
Copy link
Owner

That would work, though it's not possible to skip initial renders in vdom sadly.

Another option might be to allow passing (worker, state) to the main thread side of stockroom? You'd be duplicating the state object from the worker thread, but it seems a decent compromise and it would only add a couple bytes to the library.

@mrhein
Copy link

mrhein commented Sep 30, 2018

you could skip first render in a mechanic that you apstract your index...

Think about your normal app is in index.jsx now you add a entry.jsx and link you bundle to entry.jsx instead, export your Store from index.jsx.

now inside of entry.jsx

import Index, { Store } from './index'
import { h, render } from 'preact'

if (DEVMODE && !PRERENDER) {
  require('preact/devtools')
}

Store.subscribe((state) => {
  if (state.warmupDone) {
    const app = document.getElementById('app')
    const body = document.body

    render(<Index store={Store} />, body, app)
  }
})

...but this also require that you have some auto warmup action inside of your worker that set a state like warmupDone....

but this will delay your render in my example about 300 ms but it doesn't metter because i use a prerender engine built on top of preact-render-to-string in the background but you have to think about something like that otherwise this will delay first meaning full render

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

4 participants