Like A Girl

Pushing the conversation on gender equality.

Code Like A Girl

Think ‘React’ively

Make a simple app — Part I

As many of you must have gone through infinite number of documentations of react for understanding the framework. Here I present a collective view of how React works by building a simple Todo app.

The Todo app of ours will allow you to save, edit and delete memos(a functionality similar to Sticky notes).

React allows you to develop independent elements in your UI which can be integrated later in one class.

When you think of a Todo app, you can basically imagine a section which will contain a input box and a save button and another section which can be used to display all the saved memos.

React allows you to develop independent components of UI. How? By using class.

class demo extends React.Component{
}

React later allows you to integrate those UI components. Again how?

Create a parent class and call all the UI components in it.

class Parent extends React.Component{
render(){
return(
<div><demo /></div>
)
}
}
ReactDOM.render(){<Parent/>,document.getElementById(‘myElement’);}

render() is a function which gets triggered when any change takes place and returns the values present. This return statement inside can contain only one parent element. So, make sure that you write nested html elements.

As per the above discussion the first element to be called in React will be ReactDOM which will render the Parent class which in turn will render a demo class.

Now that we are clear with the basics, let’s get started with the app.

We will have two components in our code, one will be the save class comprising of the input box and save button and other will be the Display class which will be used for the sole purpose of displaying.

Let’s create three class, the parent class — Todo and the child classes- Save and display.

The job of Todo is to simply call all rest two components(i.e Save and Display for rendering).

We will create a static version of the UI first for simplicity and understanding.

class Todo extends React.Component{
render(){
return(
<div>
<Save/>
<Display/>
</div>)
}
}
class Save extends React.Component{
render(){
return(
<div className=’input’>
<input type=’text’/>
<input type=’button’ value=’save’/>
</div>)}
}
class Display extends React.Component{
render(){
return(<div></div>)
}
}
ReactDOM.render(<Todo/>,document.getElementById(‘root’));

Now that, you have created the static version of it you need to identify the components that are changeable.

In this particular app, the value of input box and the display class will keep on changing.The next question is how do we implement that?? The concept of state and props will come into the picture now. You can go to the this link for going into the details of it.

We have an inheritance something like this:

All the state changes in React are controlled by the Parent Class i.e. our Todo class.

Let’s first play with the input box. Every time, a user clicks the save button the value in the input box needs to change. As this app is an interactive app, we need to use state. State should be managed by top-level component. What we will do is we will add a constructor(A constructor is used to set the initial state of a component in react).

Let’s deal with one component at a time. We will start with the Save component. We will first initialize the value of input box and as it’s react, the hierarchy has to be maintained always.Go ahead and initialize your components like this — -

class Todo extends React.Component{
constructor(props){
super(props);
this.state={
input:''
}
}
render(){
return(
<div>
<Save text={this.state.input}/>
<Display/>
</div>)
}
}
class Save extends React.Component{
constructor(props){
super(props);
this.state={
input:this.props.text
}
}
render(){
return(
<div className=’input’>
<input type=’text’ value={this.state.input}/>
<input type=’button’ value=’save’/>
</div>)}
}
class Display extends React.Component{
render(){
return(<div></div>)
}
}
ReactDOM.render(<Todo/>,document.getElementById(‘root’));

Now, after doing this the input box will become non-editable. Don’t worry that is intentional. Let’s define an onChange() function on the input for capturing user events.

class Save extends React.Component{
constructor(props){
super(props);
this.state={
input:this.props.text
}
this.changeText=this.changeText.bind(this);

}
changeText(e){
this.setState({
input:e.target.value
})
}
render(){
return(
<div className=’input’>
<input type=’text’ value={this.state.input} onChange={this.changeText}/>
<input type=’button’ value=’save’ onClick={this.addtoTodo}/>
</div>
)
}
}

After this, observe that your input box has become clickable again. What we are doing is in the function we are assigning the state of the function to an event, so that when the event gets triggered the value associated to it gets stored in the state.Also take a note that — — whenever setState is called the render function gets called, I hope now you understand why we need to initialize the input box value.

The next thing is saving that input value to some state in our save button.For doing so, let’s add an onClick() to our button.

Our code will look something like this:

class Todo extends React.Component{
constructor(props){
super(props);
this.state={
input:’’,
list:[]
}
this.addTodo=this.addTodo.bind(this);
}
addTodo(savetext){
var list=this.state.list;
list.push(savetext);
this.setState({
list:list
})
//console.log(list);
}
render(){
return(
<div>
<Save text={this.state.input} saveText={this.addTodo}/>
<Display/>
</div>
)
}
}
class Save extends React.Component{
constructor(props){
super(props);
this.state={
input:this.props.text
}
this.changeText=this.changeText.bind(this);
this.addtoTodo=this.addtoTodo.bind(this);
}
changeText(e){
this.setState({
input:e.target.value
})
}
addtoTodo(){
this.props.saveText(this.state.input);
this.setState({
input:’’
})
}
render(){
return(
<div className=’input’>
<input type=’text’ value={this.state.input} onChange={this.changeText}/>
<input type=’button’ value=’save’ onClick={this.addtoTodo}/>
</div>
)
}
}

What we are doing here is that we are maintaining the hierarchy in react framework. The function is getting passed as props to the child component. If the parent value changes this.state.input then the value will be re-rendered by the parent. Also, this.props.saveText is immutable for the child class i.e Save.

If you want to check whether the input values are getting saved or not, just uncomment the console.log() in Todo class.

Let’s move to the display part of the code. As we have our list already present in the Todo class, so we will just pass it as state and receive it as props in the Display class.

class Todo extends React.Component{

render(){
return(
<div>
<Save text={this.state.input} saveText={this.addTodo}/>
<Display display={this.state.list}/>
</div>
)}
}
class Display extends React.Component{
constructor(props){
super(props);
}
render(){
return(
<div>{this.props.display}</div>
)}
}

Note that now when you type in and press the button, all the strings are getting concatenated. We need to do a small modification in our Display class.

class Display extends React.Component{
constructor(props){
super(props);
this.state={
todos:[]
}
}
componentWillReceiveProps(nextProps){
this.setState({
todos:nextProps.display
})
}
render(){
var i=1;
var renderList=this.state.todos.map((name) =>{
return <div key={i++}>{i-1}. {name}</div>;}
);

return(
<div>{renderList}</div>
)
}
}

Why Map??

Map calls a callback function once for each element in array and constructs a new array from the result. Callbacks are invoked only for indexes of array for which there are defined values.

In the above code, => is the arrow function. This syntax is introduced by ECMAscript6 which is just used for mapping a function.All of the above code is basically equivalent to

var renderList=this.state.todos.map(
function(name){
return <div key={i++}>{i-1}. {name}</div>
})

To see the working code for Todo App, fork the repository doNoteRemember on Github.

Refer Part II for more. Thanks for reading!!