Development Beginner's experience with React - a shout for feedback

Ms-mousa

Member
Local time
03:43
Joined
Oct 22, 2019
Messages
5

Hi there!
I'm a react beginner and not really sure if this is the right place to post a call for feedback. I want to share my experience writing my first web app with react. It's a weather App inspired by This Post by Hamed

You can find the app here : MiniWeather.ms-mousa.now.sh and the codebase here GitHub

A quick breakdown of the app:


First Screen can show weather in 4 locations with 4 cards that have different background colors based on the temp in that location.

On hover, the card pops up and a "MORE" link shows up:


Second screen shows the detailed forecast in the next 4 days in that location:

Before you read my next words, last time I did something for the web JQuery was the HOT THING! So kindly keep that in mind!

---

Things I need feedback on:

  • Component structure!
I think I should have done one from the start. I eventually had to do that. But it was difficult to do at the beginning cus I kept adding new things to it slowly. And will still develop a third screen. Yet, I DID spend hours rethinking my app structure.
The current structure is like this:

[APP] -> [WeatherEngine (API Input)] -> [WeatherCard(More link)] -> [ForecastEngine] (API Input ] -> [ForecastCard]
My main question is what is the right way to decide what should be its own component and shouldn't be?
  • CSS-in-JS or not?
To start with, React components are not short! Like I needed to right many function to process the data from the APIs. Then I read about keeping the CSS inside JS and it would have made my components waaaaaay longer and less readable. What is the best practice for this? Keep it separate or include it in the component?
  • Is it normal to have to write that much code?
I know this sounds silly, but it still seems a LOT of code just to structure a basic component and add some stuff to it. Am I doing it wrong? or this is the standard? Also the nesting seems a bit too much! functions inside component functions inside that API processing functions!
  • What's the best way to 'ADD' a component on the click of a button?
What I ended up doing is to add a function (refer to my previous point) that switches a count variable and based on that shows two or three instances of the component. VDOM diffing works here for me cus when I add a new component, the old one stays as is. That still sounds like a very bad way to do it though. Any better ways? Here is my implementation:

JavaScript:
 const [count , setCount] = useState(1);

  const show = () => {
    switch (count) {
      case 2:
          return (
            <div className='container' >
                <WeatherEngine/>
                <WeatherEngine/>
            </div>
          );
      case 3:
          return (
            <div className='container'>
                <WeatherEngine/>
                <WeatherEngine/>
                <WeatherEngine/>
            </div>
          );
      case 4:
          return (
            <div className='container'>
                <WeatherEngine/>
                <WeatherEngine/>
                <WeatherEngine/>
                <WeatherEngine/>
            </div>
          );
      default:
        return (
          <div className='container'>
            <WeatherEngine/>
          </div>
        );
    }
  • This is more of a comment:
This idea of React has to return a div that contains other things and all results in too many divs! The markup has empty divs just to return two component togethers! So what's the best way to handle this?
  • Is this the proper way to do conditional rendering? Looks off to me but works just fine!
JavaScript:
return(
    <div>
     {
      //  render welcome screen to show the search component initially
       loading === null && cod === 0 ? //   matching the initial state
        <div className='welcome'>
          <Search getWeather = { getWeather } />
        </div>
       :
       loading === true ? // if loading is true - search button is pressed - show a loading icon
       <div className='loading'>     
        <i className='fas fa-spinner fa-4x spinner '></i>
       </div>
       :
       temp !== 0 && cod===200 ? // if temp is updated and cod is 200 as in successful API response
       <div>
        <WeatherCard 
          maxTemp = { main.maxTemp }
          minTemp = { main.minTemp }
          temp ={ main.averageTemp } 
          city = { city }
          country = { country }
          main = { weather.main }
          id = { weather.id }
        />
       </div>
       :
       loading === false ? // if loading is then error happend
       <div className="welcome">
         <Error cod = { cod } errorMessage= { errorMessage } />
         <Search getWeather = { getWeather } />
       </div>
       :
       <h1>dunno</h1> // we never get to this point so yeah dunno!
     }
     </div>

That's all!

Thanks for reading till here if you did! :)

 
Upvote 2
D

Deleted member 859

Guest

Looking really awesome! Alright here are some random thoughts.

My main question is what is the right way to decide what should be its own component and shouldn't be?

The easy and simple answer is.. if you find yourself writing code (javascript, styles, etc.) multiple times, you should think about extracting it into a common component. I like to think of your base building blocks as "primitives". These are inputs, buttons, headers, and even things like a "FlexContainer" component could be super useful. I throw all these components in a common directory away from the rest of the stuff.

Then there are components that combine the primitives into a specific view or subview. The most important thing to keep in mind here is to keep your presentational components separate from your container or stateful components. Dan does a great job of explaining these concepts in an article from 2015 that is still surprisingly relevant. Custom react hooks could take the place of the container/stateful components, but that's besides the point really.

CSS-in-JS or not?

Comes down to personal preference. In most of my larger projects I've found myself using CSS modules. Looks like you might be using CRA so here's that documentation. For smaller projects I tend to use styled-components.
Is it normal to have to write that much code?

I kinda answered this in my previous responses. Splitting into primitive, presentational, and container components will help keep each them smaller and easier to work with. Once these are split, the styles become split as well, allowing for more modularity as your app continues to grows.
What's the best way to 'ADD' a component on the click of a button?

You'll need to keep the state of your button click in a container/stateful component, then render a different subtree based on that state. Looks like the button click is taking you to a completely different page though and in that case, something like react-router can be super handy.
What I ended up doing is to add a function that switches a count variable and based on that shows two or three instances of the component.

Here's what I would do:
JavaScript:
const [count , setCount] = useState(1);

const show = () => {
    let engines = [];
    for (let i = 0; i < count; i += 1) {
        engines.push(<WeatherEngine key={i} />);
    }
    return (
        <div className='container'>
            {engines}
        </div>
    );
}

Using the array index as a key is bad practice because react could become confused about what components need to re-render based upon a change to the underlying data. More information here.
Is this the proper way to do conditional rendering?

You're right that it looks off. It's very hard to read as well. Few things on this.
  1. The welcome card could be split into it's own component and encapsulate the error logic
  2. Loading could be pulled out into a dumb presentational component as well.
  3. Early exit if you are loading, if there's an error, etc
So with these things in mind, here's how I would approach this component exactly how it is currently.
JavaScript:
const Welcome = ({ getWeather, errorMessage, cod }) => {
    let error;
    if (errorMessage && cod) {
        error = <Error cod={cod} errorMessage={errorMessage} />;
    }
    return (
        <div className="welcome">
            {error}
            <Search getWeather={getWeather} />
        </div>
    );
}

const Loading = () => (
    <div className='loading'>
        <i className='fas fa-spinner fa-4x spinner '></i>
    </div>
);

const WeatherEngine = ({ /* your props */ }) => {
    // the engine part of the weather engine

    if (loading) {
        return <Loading />
    }

    if (cod !== 200) {
        return (
            <Welcome
                getWeather={getWeather}
                errorMessage={errorMessage}
                cod={cod}
            />
        );
    }

    return (
        <WeatherCard
            maxTemp={main.maxTemp}
            minTemp={main.minTemp}
            temp={main.averageTemp}
            country={country}
            main={weather.main}
            id={weather.id}
        />
    );
}

Let me know if you have any more questions!

 
Last edited by a moderator:

Ms-mousa

Member
Local time
03:43
Joined
Oct 22, 2019
Messages
5

Wow! Firstly thanks for taking the time to dig into things that deep! Deeply appreciated!

I don't have any other questions but my main takeaways are:

  • Thinking about structure in terms of containers, presentations and primitive containers. Also trying to get a rough idea of what and how many components will the app need to be at V1. Then I guess if you've done a good job that structure would allow you to grow the app in a smooth way. It's probably something I'd get with experience though... So yeah gotta work on that
  • CSS modules sounds really good! Will start adopting that for sure. Will also look into styled components more.
  • Code clarity!! Really this is a huge one! I'm surprised at how much clearer a code can be after reading yours. I also think code reflects your mental state in a way I've not experienced before. The clearer your mind and thinking the clearer your code! Love that!
Thanks again! 🤜

 

leafygreens

Member
Local time
03:43
Joined
Oct 25, 2019
Messages
18

A quick breakdown of the app:
I apologise for not answering the questions you have asked. However as an Autralian I might offer a little input if I may.

My nightlight/thermometer is colour coded

Red hues for great heatiness only kick in once the temperature exceeds 27C. Maybe a a green through lime to lemon gradient might be good for temps between, say, 16C through to 25C?

Of course it all depends on your age/health/location/leanness etc

 

Ms-mousa

Member
Local time
03:43
Joined
Oct 22, 2019
Messages
5

I apologise for not answering the questions you have asked. However as an Autralian I might offer a little input if I may.

My nightlight/thermometer is colour coded

Red hues for great heatiness only kick in once the temperature exceeds 27C. Maybe a a green through lime to lemon gradient might be good for temps between, say, 16C through to 25C?

Of course it all depends on your age/health/location/leanness etc


I did actually think about this but went ahead without it for simplicity and cus I still can't imagine green and yellow depicting weather status!
Now that the whole thing is together I'll give it a shot and see how it looks.

Thanks for the input!

 
Top