0

The following is the code that I have written while learning react, I have not yet reached the point where state is used. While practicing the use of props, I encountered the error as follows: Error snapshot

I am not able to figure out why the prop is showing as undefined. I am in the very basic stage of understanding React and would appreciate any help in this. Thank you

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import moment from 'moment';
import PropTypes from 'prop-types';

let tweet = {
    message: "Something about cats.",
    gravatar: "xyz",
    author: {
        handle: "catperson",
        name: "IAMA Cat Person"
    },
    likes: 2,
    retweets: 5,
    timestamp: "2016-07-30 21:24:37"
};

let from = {
    name: "john doe",
    addressLine1: "fake house, fake lane",
    addressLine2: "fake city, fake state"
}

let to = {
    name: "jane doe",
    addressLine1: "fake-ish house, fake-ish lane",
    addressLine2: "fake-ish city, fake-ish state"
}

function Tweet( {tweet} ) {
    return (
        <div className="tweet">
            <Avatar hash={tweet.gravatar}/>
            <div className="content">
                <NameWithHandle author={tweet.author}/><Time time={tweet.timestamp}/>
                <Message text={tweet.Message}/>
                <div className="buttons">
                    <ReplyButton/>
                    <RetweetButton count={tweet.retweets}/>
                    <LikeButton count={tweet.likes}/>
                    <MoreOptionsButton/>
                </div>
            </div>
        </div>
    );
}

function Avatar( {hash} ) {
    var url = `https://www.gravatar.com/avatar/${hash}`;
    return (
        <img src={url} className="avatar" alt="avatar" />
    );
}

function Message( {text} ) {
    return (
        <div className="message">
            {text}
        </div>
    );
}

function NameWithHandle( {author} ) {
    const { name, handle } = author
    return (
        <span className="name-with-handle">
        <span className="name">{name} </span>
        <span className="handle">@{handle}</span>
        </span>
    );
}

// The {} is used when there is assignment going on inside the expression the component is pointing to,
// The () is used when there is nothing except a return of JSX from the component.
// If there is use of {} then the return statement is mandatory to return JSX and render.

const Time = ( {time} ) => {
    const timeString = moment(time).fromNow();
    return <span className="time">{timeString}</span>;
}

const ReplyButton = () => <i className="fa fa-reply reply-button"/>

const RetweetButton = ( {count} ) => (
    <span className="retweet-button-span">
        <span className="retweet-button-icon"><i className="fa fa-retweet retweet-button"/></span>
        {getRetweetCount(count)}
    </span>
);

const LikeButton = ( {count} ) => (
    <span className="like-button-span">
        <span className="like-button-icon"><i className="fa fa-heart like-button"/></span>
        {count > 0 &&
            <span className="like-count">
            {count}
            </span>}
    </span>
);

const MoreOptionsButton = () => <i className="fa fa-ellipsis-h more-options-button"/>

function getRetweetCount(count) {
    if(count > 0) {
        return (
            <span className="retweet-count">
            {count}
            </span>
        );
    } else {
        return null;
    }
}

const AddressLabel = ( {person} ) => {
    const {name, addressLine1, addressLine2} = person;
    return(
        <div className = "addressLabel">
            <div className = "person-name"> {name} </div>
            <div className = "person-address1"> {addressLine1} </div>
            <div className = "person-address2"> {addressLine2} </div>
        </div>
    );
}

const Envelope = ( {from}, {to} ) => (
    <div>
        <AddressLabel person={from}> From: </AddressLabel>
        <AddressLabel person={to}> To: </AddressLabel>
    </div>
);



LikeButton.propTypes = {
    count: PropTypes.number
};

RetweetButton.propTypes = {
    count: PropTypes.number
};

Time.propTypes = {
    time: PropTypes.string
};

Message.propTypes = {
    text: PropTypes.string
};

NameWithHandle.propTypes = {
    author: PropTypes.shape({
        name: PropTypes.string.isRequired,
        handle: PropTypes.string.isRequired
    }).isRequired
};

Avatar.propTypes = {
    hash: PropTypes.string.isRequired
};

ReactDOM.render(
    <div>
        <Tweet tweet = {tweet}/>
        <Envelope from = {from} to = {to}/>
    </div>,
    document.querySelector('#root')
);

1 Answer 1

1

You have to destructure from and to from the same props object in Envelope:

const Envelope = ( {from, to} ) => (
    <div>
        <AddressLabel person={from}> From: </AddressLabel>
        <AddressLabel person={to}> To: </AddressLabel>
    </div>
);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.