How to pass props between different components in React

In our last post, we have looked at the difference between state and props with examples. In this post, I’ll explain how we pass props to a different component.

A common question followed by this act is why do we pass props to a different component? That’s because to make our component dynamic. We want to change our state of the component as soon as some event is evoked. Passing props looks very much like custom HTML attributes to which you assign your data with JSX syntax.

Let’s look at an example:-

Here, I have created a simple application that will display a message. The application contains 4 radio buttons and 2 checkboxes to change the style of the font. So whenever a user interacts with the radio button or checkbox the style of the font will change based on their values.

To achieve this I have created two component Style and DisplayMessage.


class DisplayMessage extends React.Component {
    constructor(props) {
        super(props)
    }

    render() 
    {
        const style = {
            color: this.props.color,
        }

        var msg;
        if (this.props.italic && this.props.bold)
            msg = <strong> <em> {this.props.value} </em> </strong>
        else if (this.props.italic)
            msg = <i> {this.props.value} </i>
        else if (this.props.bold)
            msg = <b> {this.props.value} </b>   
        else
            msg = this.props.value
            
        return (
            <h1 style={style}> {msg} </h1>
            );
    }
}

In the above components, we have received props from a parent class. The way we use the value of props is by using this the instance of the class. Note that since it is a child component it does not know whether the incoming props are state or props from the parent component. It will take every data as a props pass through it. And DisplayMessage component will re-render itself whenever incoming props is changed.

Now let’s look at the Style component:-


class Style extends React.Component {
    constructor(props) {
        super(props);
        this.state = { 
            color:null,
            bold:false,
            italic:false,
        }
        this.onChangeColor = this.onChangeColor.bind(this);
        this.onChecked = this.onChecked.bind(this)
    }
    
    onChangeColor(e) {
        this.setState({color : e.target.value})
    }

    onChecked(kind) {
        if (kind === 'bold')
            this.setState({bold:!this.state.bold});
        else
            this.setState({italic:!this.state.italic});
    }

    render() {
        return (
            <div className="App">
             <img src={require('./img1.jpg')} />
             <div className = "container">
               <div className = "row">
                  <div className = "col-sm">
                  <label>
                    <input type='radio' value = 'red'  checked={this.state.color === 'red'} onChange={this.onChangeColor} /> Red
                  </label>
                   </div>
                   <div className = "col-sm">
                 <label>
                    <input type='radio' value = 'blue'  checked={this.state.color === 'blue'} onChange={this.onChangeColor} /> Blue
                 </label>
                </div>
                   </div>
               <div className = "row">
                  <div className = "col-sm">
                  <label>
                    <input type='radio' value = 'green'  checked={this.state.color === 'green'} onChange={this.onChangeColor} /> Green
                  </label>
                   </div>
                   <div className = "col-sm">
                 <label>
                    <input type='radio' value = 'yellow'  checked={this.state.color === 'yellow'} onChange={this.onChangeColor} /> Yellow
                 </label>
                </div>
                   </div>
               <div className = "row">
                   <div className = "col-sm">
                  <label>
                    <input type='checkbox'  checked={this.state.italic} onChange={(e,kind) => this.onChecked('italic') } /> italic
                  </label>
                </div>
                 <div className = "col-sm">
                  <label>
                    <input type='checkbox'  checked={this.state.bold} onChange={(e,kind) => this.onChecked('bold') } /> bold
                  </label>
                 </div>
              </div>

             <DisplayMessage 
                value = "Welcome" 
                color = {this.state.color} 
                bold={this.state.bold} 
                italic={this.state.italic} 
                />
             </div>
            </div>
        );
    }
}

Note that I have used here Bootstrap for simplicity

In the component constructor, we have created a state which stores the color of the message and style of the message i.e. whether it is bold or italic or both.

Then we have two functions:

  • onChangeColor()function which will change the color value of state if that radio button is checked.
  • onChecked()function which will toggle bold and italic value of our state.

And in the last, we pass all this value to our DispalyMessage component. Which will then be treated as props in that component

             <DisplayMessage 
                value = "Welcome" 
                color = {this.state.color} 
                bold={this.state.bold} 
                italic={this.state.italic} 
                />

Since everything incoming if props, so we cannot change the value of props in DisplaceMessage component. But everything managed by itself is state that is why we are able to change the value of state in Style component.

And this is very important because every time the value of state from Style component changes, it is passed as props to DisplayMessage component. Since the props value is changed the DisplayMessage component re-renders itself.

Here’s what the output looks like:-

output1.png

 

output2

Leave a Reply