1

Image following object structure:

const countries = [
  {
    regions: [
      {
        cities:[
          {
            temperature: 50
          },
          ...
        ]
      }
      ...
    ]
  },
  ...
]

Now every object has a corresponding component: <Country/>, <Region/>, <City/>. The state is stored and managed in a context. You can click on a City to refresh it's current temperature (API Call). You can also click on a floating action button to update all cities.

Question

How can I trigger a refresh on each city with the floating action button, considering that every city is loading itself (for UX reasons) and show a loading animation until they are done loading. If I just get the whole object from the API again with all countries, regions and cities, I have no control over when which table is finished and can't show an animation accordingly.

Best solutions i could think of

Create an event emitter kinda thing, and trigger each city onRefreshClicked. Or create a subscriber functionality in which you can pass a callback, like you do with web sockets.

But feel like my solutions are an anti-pattern and against the one-way data flow rule of react. Als it feels really dirty. Any ideas?

I am using react-hooks btw.

oemera
  • 3,223
  • 1
  • 19
  • 33
  • 1
    Your first suggestion doesn't sound like it would violate one-way data flow. Especially if you use a [reducer hook](https://reactjs.org/docs/hooks-reference.html#usereducer) – Seth Nov 27 '19 at 15:44
  • I already looked into that hook, but I can't see how this helps to emit an event like in my example? I don't have any redux experience to be fair. I would gladly appreciate a minimal example, if possible. – oemera Nov 27 '19 at 16:51
  • Check out https://stackoverflow.com/questions/53146795/react-usereducer-async-data-fetch – Seth Nov 27 '19 at 19:12
  • This doesn't actually adress my problem. He answers the question how to call async functions with `useReducer` and trigger actions from child components. I rather want to trigger child functions via an event from a floating action button (parent). – oemera Nov 27 '19 at 19:25
  • I guess that wasn't very clear to me in my initial reading of your question. What UX constraints are preventing you from abstracting these functions and passing them down? – Seth Nov 27 '19 at 20:13
  • I don't see why you would allow UX to dictate programming design patterns. It's very much an anti-pattern to call child component functions from a parent. It's very rarely acceptable and should be avoided in favor of conventional design patterns. The only case when it's acceptable is when you don't have access to the component source (library). In that case you can use refs. But since it's your _own_ code, don't do that. – Seth Nov 27 '19 at 20:18
  • Users are the essence of your application. Everything should work around UX imo. But what you wrote was my problem to begin with. I would never use refs for that. I rather want to pass an event to the child. Currently I solved the problem by subscribing to an `onRefresh`-handler which you can pass a callback to. The handler then calls all callback simultaenously when the floating action button is clicked. I don't like that solution tho. – oemera Nov 27 '19 at 20:25
  • Sure, users are the essence of your application. That's why you develop great user experiences that cater to their needs for a seamless and fluid experience. With that being said, that is mutually exclusive to how you program that experience. Could you start providing minimally reproducible examples? Otherwise your described solutions are hard to reason with unless they're provided with context to the problem. – Seth Nov 27 '19 at 20:33

0 Answers0