arunoda / react-komposer

Feed data into React components by composing containers.
MIT License
732 stars 71 forks source link

dispatch action in componentDidMount () doesn't get picked up by onData() immedaitely #81

Open flexlee opened 8 years ago

flexlee commented 8 years ago

Trying to implement a clock component. Once the component is rendered, I wish it to immediately show current time. I have this component:

import React, { PropTypes } from 'react';

class Time extends React.Component {
  static propTypes = {
    time: PropTypes.string.isRequired,
    updateTime: PropTypes.func.isRequired,
  }

  componentDidMount() {
    const { updateTime } = this.props;
    const time = new Date().toString();
    updateTime(time);
    console.log(time);
  }

  render() {
    const { time } = this.props;
    return (
      <div>{time}</div>
    );
  }
}

export default Time;

and container code:

import { useDeps } from 'react-simple-di';
import { composeAll, compose } from 'react-komposer';
import Time from '../../components/account/clock';

export const composer = ({ context, updateTime }, onData) => {
  const { Store } = context();

  Store.subscribe(() => {
    const { time } = Store.getState().clock;
    onData(null, { time });
  });

  const { time } = Store.getState().clock;
  onData(null, { time: time.toString() });

  const handle = setInterval(() => {
    const datetimeString = new Date().toString();
    updateTime(datetimeString);
  }, 1000);

  const cleanup = () => clearInterval(handle);
  return cleanup;
};

export const depsMapper = (context, actions) => ({
  updateTime: actions.clock.updateTime,
  context: () => context,
});

// need useDeps to inject context, from where we take out Store object
export default composeAll(
  compose(composer),
  useDeps(depsMapper),
)(Time);

However, the store update resulted from the action dispatch in componentDidMount() doesn't get picked up by onData(null, { time: time.toString() });. I guess it was loaded before componentDidMount() and Store.subscribe() only gets to update the clock 1 second later. I think I wish to know in general how lifecycle methods can play well with react-komposer.

arunoda commented 8 years ago

There's no big issue with the general lifecycle hooks. if you call onData on the top of the composer, you component get's data via proper immediately. After that, every call to onData will result in getting data.