React - Passing Props

Hello All!

I’m at the end of the React modules and I found Jamming so difficult! I’m not clear on props and when and how to pass them. I was going through the motions with Jamming without fully understanding what I was doing.

Am I right in saying that you pass a prop by naming an attribute and giving it a value in an instance of a component? And then in the actual component you call this.props.atrributeName? Why do we do that this latter step?! Why is there so much back and forth, passing props from here to there?

As always, your help is very much appreciated!

Vicky :smiley:

For anyone who is interested I am finding this article quite helpful: An Analogy to Help You Understand React’s Lifecycle Methods.

1 Like

Hi Vicky,

I am also stuck in the infamous jammming project right now, so believe me I feel your pain :smiley: .

But with regards to props, I think this link helped me a lot, together with the next section that talks about state and how you combine both in action. That and something that also helped me a lot was doing this final exercise/mini-project in their docs. I think React has done an amazing job with their docs to be honest. That could be part of the reason for their success.

What helps me a little with props is thinking of this game where there’s a group of people and one of them has to whisper a secret message to the ear of the one at their side, and this one in turn whispers the secret to the ear of the next one, and so on. The final person of the chain will receive this message, but if you’re not part of the chain, you don’t know what the message is, right? Well, this is what happens with props:

You make a component A:

class ComponentA extends ... {
    
}

Then, that component will have, for example, a method (although this also applies to the state) that for example, logs something to the console.

So…

class ComponentA extends ... {
    // In the constructor you bind
    // the method, etc, etc 
    constructor ...
    

    logMyValue(myValue) {
        console.log(myValue);
    }
}

Now, let’s suppose that ComponentA wants to print a value you type into another component. How will ComponentA know what value to print? And when will it know to print it?

That is why, when you create the component that has the input where you typed you pass the prop of the logMyValue “ability” if you want, and the child component will contribute the value. See:

class ComponentA extends ... {
    // In the constructor you bind
    // the method, etc, etc 
    constructor(props) ...
    

    logMyValue(myValue) {
        console.log(myValue);
    }

    render() {
        return (
           // Here componentA whispers the method to CompB
            <ComponentB logValue={this.logMyValue} />
        );
    }
}

class ComponentB extends ... {

    handleChange(event) {
        // Here you assign the value you typed to a variable...
        const value = event.target.value;

        // ...that then you use as arg for the logValue method of CompA
        this.props.logValue(value);

        // But wait, how did this method get here if it's in CompA?
        // It was whispered by CompA. Check above, inside CompA.
    }

    render() {
        return (
            // Here, you tell the input in CompB: whenever you change,
            // handle the event with this method (this.handleChange)
            <input type="text" onChange={handleChange} />
        );
    }
}

And then the whisper chain can even come back with an answer, too!
For example, if you want to change the state of CompA for some reason, you could add a this.setState() call inside this method declaration (in CompA) and when you call it in CompB, the state of the former will be updated, right?
Like this:

class ComponentA extends ... {
    // In the constructor you bind
    // the method, etc, etc 
    constructor(props) {
        super(props);
        this.logMyValue = this.logMyValue.bind(this);
        this.state = {
            value: 'Nothing now! :('
        }
    }    

    logMyValue(myValue) {
        this.setState({
            value: myValue
        })
        console.log(myValue);
    }

    render() {
        return (
            <ComponentB logValue={this.logMyValue} />
        );
    }
}

class ComponentB extends ... {

    handleChange(event) {
        const value = event.target.value;
        this.props.logValue(value);
    }

    render() {
        return (
            <input type="text" onChange={handleChange} />
        );
    }
}

That above would now update the state of CompA with the value you passed from CompB. There was effectively another whispering chain back, in a way.
Jokes aside, I hope the example will help a little to understand this, which I know, it’s a little bit tricky.

1 Like

Thanks so much for your detailed reply! I found another article and this final paragraph of it helped me:

The concept of a component means we can split a very complex application down into many small components.

With a component, we also have to have a way to transfer data into these components. This is where the concept of a prop comes in, because a function component acts much like a function, think of props as an object we pass as an argument much like a function.

We can define the prop by the attributes of the JSX that represents the component. We saw an example of this. This means we can render multiple iterations of the same component with different data.

1 Like