Bram Kuitert
Bram Kuitert

Reputation: 51

ReactJS component only recognizes first parameter I pass

I'm encountering an issue where a modal component only receives the first parameter I send it but I need it to recognize both parameters or else the modal has no use. Basically, right now I can choose whether I put my TaskProps or a closeModal function as the first parameter. If the TaskProps are the first parameter, the closeModal function gets a TypeError and does not get recognized as a function. If I put closeModal as the first parameter, I'm able to close the modal but I can't work with the TaskProps to show details about certain tasks.

Here's my (relevant) code:

index.js ->

const TaskList = (state: TaskSectionState, task): React$Element<React$FragmentType> => {
    const [tasks, setTasks] = useState([])
    const [isSortDropdownOpen, setIsSortDropdownOpen] = useState(false);
    const [selectedTask, setSelectedTask] = useState(tasks[1]);
    const [openModal, setOpenModal] = useState(false)
    
    const selectTask = (task) => {
        setSelectedTask(task);
        setOpenModal(!openModal)
    };
    
    {openModal && <DetailModal {...selectedTask } closeModal={setOpenModal}  />}

DetailModal.js ->

type TaskProps = {
    id: number,
    title: string,
    assigned_to: string,
    assignee_avatar: string,
    due_date: string,
    completed: boolean,
    priority: string,
    stage: string,
    checklists: Array<ChecklistsItems>,
    description: string,
    attachments: Array<AttachmentsItems>,
    comments: Array<CommentsItems>,
};

const DetailModal = (task: TaskProps, {closeModal}): React$Element<React$FragmentType> => {
    const [completed, setCompleted] = useState(task.completed == true);
    
    return (
        <React.Fragment >
            <Modal show={true}>
            <Card>
                <Card.Body>
                   <h3>Task Details</h3>
                    <hr className="mt-4 mb-2" />

                    <Row>
                        <Col>
                        <p className="mt-2 mb-1 text-muted">Title</p>
                            <h4>{task.title}</h4>

                            <Row>

                                <Col>
                                    <p className="mt-2 mb-1 text-muted">Deadline</p>
                                    <div className="d-flex">
                                        <i className="uil uil-schedule font-18 text-primary me-1"></i>
                                        <div>
                                            <h5 className="mt-1 font-14">{task.due_date}</h5>
                                        </div>
                                    </div>
                                </Col>
                            </Row>

                            <div className="row mt-3">
                                <div className="col">
                                <p className="mt-2 mb-1 text-muted">Description</p>
                                    <div id="taskDesk" dangerouslySetInnerHTML={createMarkup(task.description)}></div>
                                </div>
                            </div>

                            <div className="row mt-3">
                                <div className="col">
                                    <h5 className="mb-2 font-16">Notes</h5>
                                    <p>Add notes/remarks for your future-self down below.</p>
                                </div>
                            </div>

                            {/* add comments */}
                            <Row className="mt-2">
                                <Col>
                                    <div className="border rounded">
                                        <form action="#" className="comment-area-box">
                                            <textarea
                                                rows="3"
                                                className="form-control border-0 resize-none"
                                                placeholder="Your comment..."></textarea>
                                            <div style={{height: "60px"}} className="p-2 bg-light">
                                                <div className="float-end">
                                                    <button type="submit" className="btn btn-primary">
                                                        <i className="uil uil-message me-1"></i>Add Note
                                                    </button>
                                                </div>
                                                <div>
                                                    <Link to="#" className="btn btn-sm px-1 btn-light">
                                                    </Link>
                                                    <Link to="#" className="btn btn-sm px-1 btn-light">
                                                    </Link>
                                                </div>
                                            </div>
                                        </form>
                                    </div>
                                </Col>
                                <div className="text-end"  style={buttonStyle} >
                                <Button variant="light"type="button" className="me-1" 
                                onClick={() => closeModal(false)}>
                                    Close
                                </Button>
                                <Button variant="secondary">
                                    Update Details
                                </Button>
                            </div>

                            </Row>
                        </Col>
                    </Row>
                </Card.Body>
            </Card>
            </Modal>
        </React.Fragment>
    );
};

export default DetailModal;

To make things maybe a bit more clear, if I pass my parameters in the manner which is shown above in DetailModal.js (TaskProps first and closeModal second) the details get rendered in the modal but the following TypeError shows up when clicking the 'Close' button:

enter image description here

And when I pass the parameters the other way around like this I'm able to close the modal perfectly fine but the TaskProps don't get passed and it just leaves blank fields. (See screenshot)

const Task = ({closeModal}, task: TaskProps): React$Element<React$FragmentType> => {
    const [completed, setCompleted] = useState(task.completed == true);

enter image description here

I would love to finally get past this headache because I can't seem to figure it out myself. I appreciate any input tremendously!

Upvotes: 1

Views: 386

Answers (1)

Gleb Kostyunin
Gleb Kostyunin

Reputation: 3863

For react components first argument is an object representing all the props passed to it. So in your case for it to work you have to do it this way:

const DetailModal = ({closeModal, ...task}) => {

This way, you are destructuring closeModal from this object and keeping all the other props grouped together as a task.

Upvotes: 2

Related Questions