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:
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!
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! :)
Top comments (12)
I personally like it, how the code looks at the end depends a lot on what you are using, with styled-components you will get a new component for your styles and you could move that component to another file if it makes sense.
But if you are more comfortable using CSS outside JS do it, it’s not a requirement, eventually when you start to make bigger apps in bigger teams you may reach a point you could justify the usage of CSS in JS.
I have seen a lot of people like CSS modules because they are CSS but still encapsulated.
I'll look into styles components more...
The Idea of the CSS modules looks really good! I think it's a good balance and actually solves the problem in an elegant way
React has something called React.Fragment for exactly this reason. Read more on reactjs.org/docs/fragments.html
Yup that looks great! will start using that for sure! Thanks for the tip
There is an excellent shorthand for fragments too!
The thing is If you need to process API data for example and have to make a couple of functions to do that. Would be better to have the processing in one component and the display in another?
Cus for this project I was thinking to have ONE component to process both current weather AND forecast and then return the values back and then I'd decide which one to display and which one to pass to which component. I think that is a very logical way to think about it. But then with the one way data flow in React not sure if it's possible.
You could Imagine one parent search Component -> API engine -> Display component
But those display component need to send back data to API engine again if the user wants to update the request or something.
What do you think?
There are multiple ways, I wrote an article about this sergiodxa.com/articles/react-condi... and the React docs has a section about this topic reactjs.org/docs/conditional-rende....
The tl;dr off there is no single way, use any JS way to handle conditions.
Render the component conditionally based on a a state, when you click the button change the state value so the component will be rendered by React.
So yeah Not very different from what I did...
I just thought maybe there is another more clever way....