React at TechLabs
React essentials for beginners
- React at Techlabs
- The team
- The gameplan
- Folder structure
- Component creation
- React state
- Controlled components
- Lifting state up
- Local storage
- Conclusion
React at Techlabs
Last semester I was a web development mentor for the digital shaper programm of TechLabs. The program equips young people with state-of-the-art tech skills in the fields of data science, artificial intelligence, web development and ux design.
Groups of 4 - 6 students get assigned a mentor who helps them navigating through the learning journey of 8 weeks online learning + 8 weeks project phase.
The team
My team of 6 ux design and web development "techies" was super motivated to learn the fundamentals of frontend web-development and therefore quickly acquired the necessary HTML and CSS skills to then get started with javascript and react.
The gameplan
My roadmap for getting the techies familiar with core concepts and architectural structures of react looked the following:
Folder structure: Learn how to set up and structure a react project into components, utils, assets and configuration files.
Component creation: Learn how to create the building blocks of a react application with functional components.
React state: Understand component level state and get up and running with the useState hook.
Controlled components: Understand the difference between controlled and uncontrolled components.
Lift state: Lift and pass state across components to share state throughout the app.
Local storage: Learn how to utilize browsers local storage to add rapid prototyping techniques to the project.
Let's dive in, to see what we learned together over the course of 8 weeks:
Folder structure
Structuring my react projects has been something I neglected for a long time as I was working mainly alone on my projects. Only with increasing collaborative project work I understood the importance of clean and well-structured react folder architecture for project maintenance.
Together we learned, that every react-project has a root a src and from there on a folder structure that is highly unopinionated.
Though, I shared what I think every react-project should be structured at its very core, which namely are following folders:
Components: This folder holds all our functional components. We could also subdivide this folder further into stateful and stateless components.
Assets: This folder contains the tangible assets we use in our application such as images, icons and json data. (I find that for rapid prototyping its always good to have quick access to some json mock data)
Utils: This folder holds all our utitities and helper functions. These are little code snippets that help us throughout our application.
root
- src
--- assets
----- images
----- icons
----- json
--- components
----- header
----- footer
----- button
--- utils
--- pages
I was very happy that the rather basic session around structuring a react application already sparked excitment in the team. It helped the team to get up and running with the project and hence, empowered and motiviated them to execute on the project even more.
"Overwhelmed by our fast progress we presented our results to Lukas, our mentor. Lukas was able to give us a lot of feedback and helped us with the folder structure of the react app and with making our code cleaner. He also introduced us to “live share” for VS code, so that we were able to work together in one coding editor."
Component creation
Components are the building blocks of any react application. In the TechLabs track we looked at how to create functional components, split them into smaller ones and reuse them throughout the application. We learned that each react component is a function that accepts input in the form of objects passed as props and that each function returns HTML.
Registration.js
const Registration = ({data}) => {
const accountState = data.accountState;
return(
<h1>Registration page</h1>
...
)
}
export default Registration;
some other component
...
<Route path='/registrieren'>
<Registration /></Route>
...
React state
Our next session was fully dedicated to addition of state to our components and the understanding of how stateful logic makes and breakes a react application. We used the useState hook and learned that it is no more than a value pair that returns a state variable as well as a function which updates our state whenever we call it. The component subsequently re-renders everytime we mutate state.
Modal.js
...
const [show, setShow] = useState(false);
handleShow = () => {
setShow(!show)
}
return(
<>
...
{show && <Modal/>}
...
<button onClick={handleShow}>See more</button>
...
</>
)
...
Controlled components
By default HTML form elements such as text inputs, checkboxes and radio buttons manage their own internal state. In other words: We can directly type in anything we want into our input fields without giving our app specific instructions on what to do with the value of the element we are targeting. Its a traditional HTML behaviour and commonly referred to as uncontrolled components.
uncontrolled component
...return(
<>
...
<input
type='text'
name='name'
/>
...
</>
)
...
Instead of letting the DOM manage the state of its nodes we learned how to control our UI component with its very own state. We did this by utilising reacts props and callbacks such as onChange. The onChange event handler fires a function handleChange which then handles the state change. We now have full control over our components state.
controlled component
...
const [value, setValue] = useState({
name: '',
description: '',
mail: '',
adress: '',
});
const handleChange = (e) => {
setValue({ ...value, [e.target.name]: e.target.value });
};
...
return(
<>
...
<input
type='text'
name='name'
value={value.name}
onChange={handleChange}
/>
...
</>
)
...
Lifting state up
With further development of our little web-application the group came across the issue of not being able to use state from one component in another component. It was time to lift state up!
Sharing stateful logic horizontally across the component tree can be done by removing local state from child components and letting its common parent component take care of it. The parent component can then pass the state down to its children via props. As the child component lost control over its local state accordingly, we also pass down a handleChange function that gets called within the child but updates state in the parent.
parent component
...
const [value, setValue] = useState({
name: '',
description: '',
mail: '',
adress: '',
});
const handleChange = (e) => {
setValue({ ...value, [e.target.name]: e.target.value });
};
return(
<Form
value={value}
handleChange={handleChange}
/>
)
...
child component
...
const Form = ({ value, handleChange }) => {
return(
<>
...
<input
type='text'
name='name'
value={value.name}
onChange={handleChange}
/>
...
</>
)
}
...
Local storage
After I heard of local storage as a react newbie for the first time I thought this would be super far away. How could my application be able to access my browser and then store data in there?Turns out that this is actually a pretty simple two-step concept of
saving data via localStorage.setItem()
and then retrieving (getting) it via localStorage.getItem()
I thought it would be super cool to teach localStorage in a TechLabs project as it allows the team to build more sophisticated prototypes in a quick and easy way.Our goal was to use form data in another component. With already having acquired the skills of using, lifting and controlling state, the group had no problems setting up the form itself and storing its input as an object in the forms state.We then learned to call the setItem method on a form submit. Because the web storage API only stores key value pairs as strings we also had to stringify the form object.
form component
...
const [value, setValue] = useState({
name: '',
description: '',
mail: '',
adress: '',
});
const handleSubmit = () => {
localStorage.setItem('value', JSON.stringify(value));
};
return(
<>
...
<button onClick={handleSubmit}>Register</button>
...
</>
)
...
In the component where we wanted to have the data, we used the useEffect hook. It helps us to invoke the fetching of our storage items on inital page render and fetch our stored items by calling getItem. We additionally had to parse the string to convert it back into a javascript object.
other component
...
const [value, setValue] = useState(null);
useEffect(() => {
setValue(JSON.parse(localStorage.getItem('value')));
}, []);
return(
<>
...
<h1>{value && value.name}</h1>
...
</>
)
...
Conclusion
Getting the basics right early on is important to build robust things with react. While there are many more practices to master, I personally think that these 6 concepts provide a good starting point to understand what react is capable of. In my opinion react has a smooth learning curve in general and can be a soft gateway into the world of javascript.