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 Tribes page to React (finishing the feature) #1145

Merged
merged 7 commits into from
Jan 19, 2020

Conversation

mrkvon
Copy link
Contributor

@mrkvon mrkvon commented Dec 11, 2019

Proposed Changes

  • Finalize the migration of /tribes page to React
  • api calls are made from React
  • there is a remaining layer of angularjs for communicating between angular and react

Testing Instructions

  • git checkout or switch to tribes-react-page, npm install, npm start
  • go to /tribes
  • See that the page works as expected; that the functionality has not degraded.
    • specifically, test when user is both signed in and signed out.
  • FYI we have not migrated some google analytics calls. So they were removed.

Finishing work on #1133
Depends on #1137, #1143 and #1144, and whatever these depend on. The dependencies should be merged to tribes-react branch first and then this branch should be rebased. (update: dependencies merged)

@mrkvon mrkvon changed the base branch from master to tribes-react December 11, 2019 00:09
@mrkvon mrkvon force-pushed the tribes-react-page branch 3 times, most recently from e49a0d1 to dc60342 Compare December 13, 2019 02:16
@mrkvon mrkvon force-pushed the tribes-react-page branch 3 times, most recently from 23b6138 to 0fc016e Compare December 14, 2019 12:30
@mrkvon mrkvon force-pushed the tribes-react branch 2 times, most recently from ba50aa6 to 1c00aa6 Compare January 3, 2020 21:11
@mrkvon mrkvon force-pushed the tribes-react-page branch from 0fc016e to 16de6ee Compare January 3, 2020 22:34
@mrkvon mrkvon force-pushed the tribes-react branch 2 times, most recently from 2aa60fe to cb50541 Compare January 5, 2020 20:31
@mrkvon mrkvon force-pushed the tribes-react-page branch from 6193cbf to f71cfdb Compare January 5, 2020 20:46
@mrkvon mrkvon requested review from simison and nicksellen January 8, 2020 01:54
Copy link
Contributor

@nicksellen nicksellen left a comment

Choose a reason for hiding this comment

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

Great, very nice to have a whole page in react, left a few discussion points.

Also, maybe this is a good time to get in the practise of adding tests, even if they quite basic - that we can render the page, and click on some tribes... or see them listed or something.

Edit: I see #1169 now :)

modules/tribes/client/components/TribesPage.component.js Outdated Show resolved Hide resolved
modules/tribes/client/views/tribes-list.client.view.html Outdated Show resolved Hide resolved
const tribes = await api.read();
setTribes(tribes);
})();
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

Async stuff in useEffect looks a bit messy, but I know this is the way it has to be because of the cleanup function return thing, just want a little moan about it.

I wonder if the aesthetics of any of these variations are more pleasing?

useEffect(() => {
  const fetchData = async () => {
    const tribes = await api.read();
    setTribes(tribes);
  };
  fetchData();
}, []);
useEffect(() => {
  async function fetchData() {
    const tribes = await api.read();
    setTribes(tribes);
  }
  fetchData();
}, []);
async function fetchData() {
  const tribes = await api.read();
  setTribes(tribes);
}

useEffect(() => {
  fetchData();
}, []);

... or ... inspired by https://github.com/rauldeheer/use-async-effect ... a small implementation of useAsyncEffect:

function useAsyncEffect(fn, deps) {
  useEffect(() => {
    let cancelled = false;
    const isCancelled = () => cancelled;
    fn(isCancelled);
    return () => { cancelled = true; };
  }, deps);
}

which would enable use like this:

useAsyncEffect(async isCancelled => {
  const tribes = await api.read();
  if (isCancelled()) return;
  setTribes(tribes);
}, []);

Happy without anything like this though, just exploring thoughts/options...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I need to choose, I like the 3rd option of defining fetchData outside, or the original one. But this is the kind of stuff that's impossible to argue about. 🙂

The useAsyncEffect looks magical, but has some additional benefits, doesn't it? Cancellation... does it stop the async function when leaving the component? Interesting!

Copy link
Contributor

Choose a reason for hiding this comment

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

No need to change anything at all here.

The useAsyncEffect isn't magical, just wrapping up the pattern you can do without it:

useEffect(() => {
  let cancelled = false;
  (async () => {
    const tribes = await api.read();
    if (cancelled) return;
    setTribes(tribes);
  })();
  return () => { cancelled = true; };
}, []);

It doesn't actually stop the async function as they don't have that feature (there was a cancellable promises proposal, but that got cancelled), axios requests can be cancelled so it's possible to connect that up too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see. The useAsyncEffect makes sure the component doesn't get updated after it's unmounted. If I observe correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

used the suggested version 3 (fetchData defined outside useEffect)
21d2106

The useAsyncEffect may have additional benefits. To be used here and elsewhere. In other PR.

@mrkvon mrkvon force-pushed the tribes-react-page branch from f71cfdb to 5810dbd Compare January 19, 2020 14:46
replace a tribe in tribes array with Array map
move tribes-list template inline
add TODO for removing controller (to be done in the future)
define the async fetchData outside of useEffect (clarification)
@mrkvon mrkvon requested a review from nicksellen January 19, 2020 15:41
@mrkvon
Copy link
Contributor Author

mrkvon commented Jan 19, 2020

@nicksellen @simison Nick's feedback is incorporated. If you like, make another round of reviews. Otherwise I'll squash and merge to tribes-react in 24+ hours. Then I'll wait for approval of the tribes-react #1148 and rebase + merge that to master. The tests can be merged in a follow-up I believe.

const handleMembershipUpdated = data => {
// update the tribes in state

setTribes(tribes => tribes.map(tribe => tribe._id === data.tribe._id ? data.tribe : tribe));
Copy link
Contributor

Choose a reason for hiding this comment

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

I found this little hard to understand (a couple of arrow functions and ternary in one line, with lots of tribe or tribes sounding things going on.). It's ok to leave as is but would there be any way explaining this with comment? 😅

Not a blocker. :-)

Copy link
Contributor

Choose a reason for hiding this comment

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

It was me that suggested to change it in this way, perhaps the clearest would be to extract a mapReplace function (which has come up in lodash discussion before, e.g. lodash/lodash#1967). Something like mapReplace(array, condition, item), which would replace the item at condition with item.

Copy link
Contributor Author

@mrkvon mrkvon Jan 19, 2020

Choose a reason for hiding this comment

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

There is also https://github.com/kolodny/immutability-helper, but I've just added a TODO for this. It's unclear for me what would be a proper place for such helpers. Feels like reinventing a wheel a bit.

Copy link
Contributor

@simison simison left a comment

Choose a reason for hiding this comment

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

/tribes page tests well. 👍

Tested both as authenticated and as non-authenticated.

FYI we have not migrated some google analytics calls. So they were removed.

I think we still get URL changes which is what matters.

const handleMembershipUpdated = data => {
// update the tribes in state

setTribes(tribes => tribes.map(tribe => tribe._id === data.tribe._id ? data.tribe : tribe));
Copy link
Contributor

Choose a reason for hiding this comment

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

It was me that suggested to change it in this way, perhaps the clearest would be to extract a mapReplace function (which has come up in lodash discussion before, e.g. lodash/lodash#1967). Something like mapReplace(array, condition, item), which would replace the item at condition with item.

@mrkvon mrkvon merged commit a207891 into tribes-react Jan 19, 2020
mrkvon added a commit that referenced this pull request Jan 20, 2020
- replace the whole /tribes page with React component
- fetch tribes from API
mrkvon added a commit that referenced this pull request Jan 20, 2020
- replace the whole /tribes page with React component
- fetch tribes from API
@mrkvon mrkvon deleted the tribes-react-page branch February 13, 2020 13:38
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.

3 participants