FormidableLabs / freactal

Clean and robust state management for React and React-like libs.
MIT License
1.65k stars 46 forks source link

Compatible with webpack Hot Module Replacement? #27

Closed zebulonj closed 7 years ago

zebulonj commented 7 years ago

Have you used freactal with webpack hot module replacement and the react-hot-loader? Just built a small test project with freactal and am not seeing component updates via the webpack-dev-server when I update files. Perhaps shouldComponentUpdate is preventing the re-render?

I'm going to look more closely as I'm able, but wanted to put this question out there in case others have an answer.

zebulonj commented 7 years ago

Here's a clue:

If I structure my code as follows:

export const provideCounter = provideState({
  initialState: () => ({ counter: 0 }),
  effects: {
    increment: () => state => ({ ...state, counter: state.counter + 1 })
  }
});

export const CounterComponent = ({ state, effects }) => {
  const increment = ev => {
    ev.preventDefault();
    effects.increment();
  };

  return (
    <div>
      <div>Count: { state.count }</div>
      <div><a href="#" onClick={ increment }>Increment!</a></div>
    </div>
  );
};

export const Counter = provideCount( injectState( CounterComponent ) );

...then changes to markup within the CounterComponent show up due to hot-module-replacement.

However, if I structure my code in the following style (merging the functional component into the injectState connector):

export const provideCounter = provideState({
  initialState: () => ({ counter: 0 }),
  effects: {
    increment: () => state => ({ ...state, counter: state.counter + 1 })
  }
});

export const Counter = provideCount( injectState( ({ state, effects }) => {
  const increment = ev => {
    ev.preventDefault();
    effects.increment();
  };

  return (
    <div>
      <div>Count: { state.count }</div>
      <div><a href="#" onClick={ increment }>Increment!</a></div>
    </div>
  );
}));

...then changes do not render with hot-module-replacement.

This may be a limitation independent of freactal. When working in redux and react-redux I always separated my functional components from my calls to connect().

davegomez commented 7 years ago

I'm trying to use fr(e)actal with Next.js and is breaking HMR too even if I use the pattern proposed by @zebulonj.

I also getting the warning message: Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.

JustFly1984 commented 7 years ago

Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.

This one is about React@16.0.0. You need to import PropTypes not from react but from prop-types npm module. It is deprecated since react@15.5 and in react@16 they will get rid of PropTypes in react completely.

davegomez commented 7 years ago

I know that @JustFly1984, but the error is coming from Freactal that's why I'm posting it here so it can be updated for a new version.

zebulonj commented 7 years ago

Should be a separate issue (not related to hit module replacement).

divmain commented 7 years ago

@zebulonj, this is a limitation of the component detection in react-hot-loader. There's not really a way for freactal to address it, so I'm going to close out this issue. @davegomez, the prop-types issue should be fixed in master. Please do open separate issues in the future - it helps to not lose track of anything :)