Is it possible to add an OnClick event in another component? - reactjs

I added an OnClick event in a custom component created by me, but it didn't work. I want to add an OnClick event to this component. When i click it, it will play a youtube video below. Is it not possible to do this?
Here is my code:
import React, { useState } from "react";
import classes from "./Feature.module.css";
import { ButtonHorizontal, ButtonCircular } from "./Buttons";
function Feature() {
const [open, setOpen] = React.useState(false);
const openVideo = () => {
setOpen((prev) => !prev);
};
return (
<div>
<ButtonHorizontal icon={faPlay} text="Watch Video" onClick={openVideo}/>
{open ? (
<iframe
src="https://www.youtube.com/watch?v=k2qgadSvNyU"
frameborder="0"
allow="autoplay; encrypted-media"
allowfullscreen
title="video"
/>
) : null}
</div>
);
}
export default Feature;
And buttons.js:
import React from "react";
import classes from "./Buttons.module.css";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faPlay} from "#fortawesome/free-solid-svg-icons";
export function ButtonHorizontal(props) {
return (
<div className={classes.buttonHorizontal}>
<FontAwesomeIcon icon={props.icon} className={classes.icon}/>
<div className={classes.text}>{props.text}</div>
</div>
);
}

You need to attach the onClick property to an actual HTML element. Something like <div className={classes.buttonHorizontal} onclick={props.onClick}> should work.
import React from "react";
import classes from "./Buttons.module.css";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faPlay} from "#fortawesome/free-solid-svg-icons";
export function ButtonHorizontal(props) {
return (
<div className={classes.buttonHorizontal} onclick={props.onClick}>
<FontAwesomeIcon icon={props.icon} className={classes.icon}/>
<div className={classes.text}>{props.text}</div>
</div>
);
}

Related

How to make a component render conditionally depending on drop down choices on button click. (REACT)

I'm trying to use element variables found in the React documentation here: https://reactjs.org/docs/conditional-rendering.html. I'm not sure why it is not rendering the component I have stored in the Output variable.
Submit:
import './Submit.css'
import React, { useEffect, useState } from "react";
import Output from '../Output/Output'
function Submit(props) {
let output;
const process = () => {
console.log(output)
if(props.src === "x" && props.tgt === "y") {
output = <Output src={props.src} tgt={props.tgt}/>
}
}
return (
<>
<button
disabled={props.src === "Source Chain" || props.tgt === "Target Chain"}
onClick={() => process()} className="submit">Submit
</button>
{output}
</>
);
};
export default Submit;
Output component:
import './Output.css'
import React, { useEffect, useState } from "react";
function Output (props) {
return (
<div className="content">;
<a className="contenttitle">{props.src} to {props.tgt}</a>
<h3 className="contentboxtitle"></h3>
<div className ="liquidassets"> </div>
<h3 className="contentboxtitle"></h3>
<div className ="liquidassets"> </div>
</div>
)
}
export default Output;
Thanks for any help!!
Use a state to control the button and use that state to render or not render your output component
import React, { useState } from "react";
export default function SystemsButtonGroup() {
const [showOutput, setShowOutput] = useState(false);
return (
<div>
<button onClick={() => setShowOutput(!showOutput)} className="submit">
Submit
</button>
{showOutput && <div>Replace this with your output component</div>}
</div>
);
}

Properly LogOut button React

can't get the logout button to work properly. I'm using React and Firebase.
Here is a portion of the code from App.js, where the function was declared
imports
import React, { useState, useEffect } from "react";
import { fire } from './fire';
import LogIn from './LogIn';
import Hero from './Hero';
import './App.css';
declaration
const handleLogout = () => {
fire.auth().signOut();
};
And here is the code from the Hero.js, where the function is used
import React from 'react';
import Contact from "./components/Contact";
const Hero = (handleLogout) => {
return(
<section className="hero">
<nav>
<h2>Welcome</h2>
<button onClick = {handleLogout}>Log Out</button>
</nav>
<div id="contact-form">
<Contact />
</div>
</section>
)
}
export default Hero;
What I'm doing wrong?
you need to get the handleLogout from props properly:
const Hero = ({handleLogout}) => {...}

How can I use useState to conditionally render?

I am trying to use useState to conditionally render a div but for the life of me I can not figure out how to do it. I think I am close but I can not see what I am doing wrong, I have entirely misunderstood how to do this. What am I doing wrong? I have written this and it does not work..
import React, { useState } from 'react'
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faWindowClose } from '#fortawesome/free-solid-svg-icons'
function ElementMenuHeader() {
const [elementMenuOpenClose, setElementMenuOpenClose] = useState(true)
const handleClick = () => setElementMenuOpenClose(false)
return (
<div id="App-Close-Element-Menu-Container"
style={{ display: elementMenuOpenClose ? 'block' : 'none'}}
>
<button id="App-Close-Element-Menu"
onClick={() => handleClick }
>
<FontAwesomeIcon icon={faWindowClose} />
</button>
</div>
);
}
export default ElementMenuHeader
Ideally I would like to be able to set the state of elementMenuOpenClose from other components too, but I will cross this bridge first I think.
You can just use a ternary operator and check a against the state in the operator condition return the div you would like based on the state:
{(elementMenuOpenClose? <div>some tags A </div>: <div>Some tags B </div>)}
You may have a parent component of ElementMenuHeader.
Let's say that is ParentElementMenuHeader.
Inside ParentElementMenuHeader component, you can define like
const ParentElementMenuHeader = () => {
const [elementMenuOpenClose, setElementMenuOpenClose] = useState(true);
...
return (
...
{elementMenuOpenClose && (
<ElementMenuHeader
setElementMenuOpenClose={setElementMenuOpenClose}
...
/>
)}
...
);
}
Inside ElementMenuHeader component,
import React, { useState } from 'react'
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faWindowClose } from '#fortawesome/free-solid-svg-icons'
function ElementMenuHeader({setElementMenuOpenClose}) {
const handleClick = () => setElementMenuOpenClose(false)
return (
<div id="App-Close-Element-Menu-Container">
<button id="App-Close-Element-Menu" onClick={handleClick}>
<FontAwesomeIcon icon={faWindowClose} />
</button>
</div>
);
}
export default ElementMenuHeader

How to change refs from one child component to other child component?

I am working on a chating app with reactjs and i have my components as:
-ChatBox
|-MessageList
|-InputArea
I want to update(re-render,basically append a "li" and scroll down automatically) MessageList component if user provides an input from Input Area.
What i have thought so far is to pass ref from chatbox to MessageList and and then use those refs in InputArea. But i think it is not a good approach. Can someone suggest me what to do.
Update:
My MessageList code:
import React, { useContext,useRef, useState, useEffect } from 'react';
import Message from './Message';
import "./MessageList.css";
import { AuthContext } from '../../Shared/Context/AuthContext';
const MESSAGES=[{convId:1, msgId:1 ,from:'u1',to:'u2',msg:"hello"},
{convId:1, msgId:2 ,from:'u2',to:'u1',msg:"hi"},
{convId:1, msgId:3 ,from:'u1',to:'u2',msg:"how ru"},
{convId:1, msgId:4 ,from:'u2',to:'u1',msg:"goood!!!"},
{convId:1, msgId:5 ,from:'u1',to:'u2',msg:"party ?!"},
{convId:1, msgId:6 ,from:'u2',to:'u1',msg:"yeah!!!"}];
const MessageList=(props)=>{
const msgBoxRef=useRef();
const [messages,setMessages]=useState(MESSAGES);
useEffect(()=>{
msgBoxRef.current.scrollTop=msgBoxRef.current.scrollHeight;
},[messages]);
useEffect(()=>{
if(msgBoxRef.current.scrollTop===msgBoxRef.current.scrollHeight)
msgBoxRef.current.scrollTop=msgBoxRef.current.scrollHeight;
},[])
const auth =useContext(AuthContext);
return (<div className="messages" ref={msgBoxRef}>
<ul>
{messages.map((msg)=>(
<Message key={msg.msgId} className={(msg.from===auth.user.userName)?"sent":"replies"} imageSrc="http://emilcarlsson.se/assets/mikeross.png">{msg.msg}</Message>
))}
</ul>
</div>);
};
export default MessageList;
Input Component code:
import React from 'react';
import {InputGroup,FormControl,Button} from 'react-bootstrap';
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faPaperPlane } from "#fortawesome/free-solid-svg-icons";
const Input=(props)=>{
return (<InputGroup className="mb-0">
<FormControl className="input-msg shadow-none" placeholder="Enter new message..." aria-label="new task" />
<InputGroup.Append>
<Button className="send-btn shadow-none">
<FontAwesomeIcon icon={faPaperPlane} />
</Button>
</InputGroup.Append>
</InputGroup>);
};
export default Input;
ChatBox code:
//TODO: IMPLEMENT CHAT CARD
import React, { useState, useRef } from "react";
import { Card } from "react-bootstrap";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faArrowLeft } from "#fortawesome/free-solid-svg-icons";
import MessageList from "./MessageList";
import Input from "./Input";
import Conversations from "./Conversations";
import "./ChatBox.css";
const ChatBox = (props) => {
const [conversation, setConversation] = useState(null);
const [backBtn,setBackBtn]=useState(false);
const selectedConv = (profile) => {
setConversation(profile);
setBackBtn(true);
};
const backBtnHandler=()=>{
setConversation(null);
setBackBtn(false);
}
return (
<Card className="frame">
{conversation ? (
<React.Fragment>
<Card.Header><FontAwesomeIcon icon={faArrowLeft} onClick={backBtnHandler}/>{" "+conversation.name}</Card.Header>
<MessageList chatId={conversation.id}/>
<Input />
</React.Fragment>
) : (
<React.Fragment>
<Card.Header>Chatbox</Card.Header>
<Conversations selectedChat={selectedConv} />
</React.Fragment>
)}
</Card>
);
};
export default ChatBox;

TypeError: this is undefined - {this.props.sections}

I'm trying to set values for a component by fathers prop, but this error pops and I don't have a clue on where is the real error
This is my component code:
import React from 'react';
import './styles.css';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
export default function Actions() {
return (
<div className="actions">
<FontAwesomeIcon className="icon" icon={this.props.fa} size="lg" />
<h1>{this.props.sections}</h1>
</div>
);
}
And this is my father component code:
import React from 'react';
import './styles.css'
import Actions from "../Actions/index"
// - - - FONT-AWESOME
import { faExternalLinkAlt } from '#fortawesome/free-solid-svg-icons'
export default function Navbar() {
return (
<div className="navbar">
<Actions sections={"Lançamentos"} fa={faExternalLinkAlt}/>
<Actions sections={"Processos"} fa={faExternalLinkAlt}/>
<Actions sections={"Paineis"} fa={faExternalLinkAlt}/>
<Actions sections={"Contratos"} fa={faExternalLinkAlt}/>
<Actions sections={"Relatórios"} fa={faExternalLinkAlt}/>
</div>
);
}
Thank you in advance for the help!
In functional components, you don't need to reference this
Class based component
Definition:
class MyComponent extends React.Component {
render () {
<div>{this.props.sampleProp}</div>
}
}
Usage:
<MyComponent sampleProps={someValue} />
Functional component
Definition:
function MyComponent({sampleProp}) {
return (
<div>{sampleProp}</div>
)
}
Usage:
<MyComponent sampleProp={someValue} />
When you use functional components you need to pass props as argument of the function, you also don't have 'this'.
export default function Actions(props) {
return (
<div className="actions">
<FontAwesomeIcon className="icon" icon={props.fa} size="lg" />
<h1>{props.sections}</h1>
</div>
);
}
That would be your final code, hope it helps.
This is for class components. For functional components it gets from the function arguments:
import React from 'react';
import './styles.css';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
export default function Actions(props) {
return (
<div className="actions">
<FontAwesomeIcon className="icon" icon={props.fa} size="lg" />
<h1>{props.sections}</h1>
</div>
);
}
Just remove this keyword from the function component, and pass props to the function too, like this:
import React from 'react';
import './styles.css';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
export default function Actions(props) {
return (
<div className="actions">
<FontAwesomeIcon className="icon" icon={props.fa} size="lg" />
<h1>{props.sections}</h1>
</div>
);
}

Resources