can we able to specify on click on the component definition itself? - reactjs

I want to create a component(comp) with onclick event handler. which should be handled by the component itself (i.e. inside the comp.js file).
if I use it inside the parent component we don't need to specify the event but it is handled by the component element(comp element).
is this possible. Any idea to develop this one.
in ParentComponent.js current behavior.
<NewComponent onClick={clickBehaviour}/>
I want like,
In NewComponent.js
const NewComponent.js = ()=>{
// Some code
const clickBehaviour = () =>{
// click behaviour
}
}
Is it possible in the current standards?

why you want to write your onClick event in parent component?
you can do it inside NewComponent.js easily.
just do this:
import React from 'react'
function NewComponent() {
const clickBehaviour = () =>{
// click behaviour
}
return (
<div onClick={clickBehaviour}>
//some jsx here
</div>
)
}
export default NewComponent
and use in anywhere you want to use without onClick event :
< NewComponent />
i cant understand well you situation but you can use forwardRef if you want (also can use old getElementById but using forwardRef is recommended).
import React, { useRef } from "react";
const NewComponent = React.forwardRef((props, ref) => (
<div onClick={() => alert("div 2 clicked")} ref={ref}>
div 2
</div>
));
export default function App() {
const compRef = useRef(null);
return (
<div>
<NewComponent ref={compRef} onClick={() => {
compRef && compRef.current && compRef.current.click();
}} />
</div>
);
}

Related

In ReactJS, how can I assign multiple ref to a single DOM?

I have a dialogue component in which I have created a ref, but I also want to pass the ref from the parent to it. How can I do this?
import { forwardRef } from "react";
export const PopOver = ({
show = false,
...
}, ref) => {
const thisRef = useRef(null);
// dealing with UI changes with 'thisRef'
return (
<div
ref={thisRef}, // How can I add a `ref` here?
....
>
Hello world
</div>
);
};
export default forwardRef(PopOver);
You can wrap it with another element and pass parent ref to it
sth like this :
<div ref={ref}>
<div
ref={thisRef}
....
>
Hello world
</div>
</div>
or if you want to replace ref you can do it in useEffect
like this :
useEffect(()=>{
if(ref.current){
thisRef.current = ref.current
}
},[ref])

component hiding

In react, There is one component A inside there is one component B I have used. There is one more component C, and inside C there is one button which is when clicked it hides the component B from component A.
How can I achieve this functionality
Using only React, you can achieve this by:
Parent/root component to all of these components has a boolean state, let's call it showComponentB. It's initialized to true.
This root component passes down the state showComponentB as a prop to Component A. In Component A, it is used to either show Component B if showComponentB is true or hide if it's false.
Root component passes a function to alter the state of showComponentB into Component C and is called when the button is clicked.
State of showComponentB is updated in root to false and that updated value is passed through to Component A and hides Component B.
You can try something like this. Hope it helps you.
import { useState } from "react";
import "./styles.css";
export default function App() {
const [isVisible, setIsVisible] = useState(true)
return (
<div className="App">
<CompA>
{isVisible && <CompB>
<CompC clickHandler={()=>setIsVisible(false)}/>
</CompB> }
</CompA>
</div>
);
}
export const CompA = (props) => {
return <>
<div style={{backgroundColor:'red', height:'200px',width:'200px'}}>Component A
{props.children}
</div>
</>}
export const CompB = (props) => {
return <>
<div style={{backgroundColor:'blue', height:'150px',width:'150px'}}>Component B
{props.children}
</div>
</>
}
export const CompC = (props) => {
return <>
<div style={{backgroundColor:'green', height:'100px',width:'100px'}}>Component C
<button onClick={props.clickHandler}>hide B</button>
</div>
</>
}

React function component with functions

Is it possible to create an instance of a function component like regular classes like c# and JAVA where you can call functions on the component? Something like:
https://codesandbox.io/s/hungry-microservice-bp292?file=/src/App.js
It must be an instance so that the component can be used multiple places with its own instance and values. Not like a static class.
import React from "react";
import "./styles.css";
import MyFunc from "./MyFunc";
export default function App() {
const addAlert = () => {
MyFunc.addAlert("dasdsad");
};
return (
<div className="App">
<button onClick={addAlert}>Add alert</button>
<MyFunc />
</div>
);
}
You are mixing different concepts of ReactJS and the underlying DOM. It is not possible to get a ref on the functional component itself. At most you can use forwardRef to get a reference to the underlying DOM element. You can read more about that Refs and the DOM and Forwarding Refs.
With that in mind you could change your approach by uplifting the state to the parent e.g.
App.js
export default function App() {
const [alerts, addAlerts] = useState(["Alert1", "Alert2"]);
const addAlert = () => {
addAlerts(alerts.concat("dasdsad"));
};
return (
<div className="App">
<button onClick={addAlert}>Add alert</button>
<MyFunc alerts={alerts}/>
</div>
);
}
MyFunc.js
const MyFunc = props => {
return (
<>
{props.alerts && props.alerts.map((alert, index) => (
<div>{alert}</div>
))}
</>
);
};
export default MyFunc;

How to toggle class of a div element by clicking on a button that is inside another functional component (another file)?

I want to toggle class of container (file 2) by an onClick on the button that is inside another component file.
The button has already an onClick function and I want to make it so it calls on two functions. Two toggle functions for the button and two class toggles for the container.
Hope it makes sense.
Here is my code so far:
Button component (File 1)
import React, {useState} from "react";
import "./Sort.scss";
const Sort = () => {
const [toggleSortIcon, toggleSortIconSet] = useState(false);
return (
<div className="tools">
<button
onClick={() => toggleSortIconSet(!toggleSortIcon)}
className={`sort ${toggleSortIcon ? "horizontal" : "vertical"}`}>
</button>
</div>
);
}
export default Sort;
Div container component that I want to change the class of (File 2)
import React, {useState} from "react";
import "./WordContainer.scss";
import UseAnimations from "react-useanimations";
const WordContainer = ({title, definition, example}) => {
const [toggleSize, toggleSizeState] = useState(false);
return (
<div className={`container ${toggleSize ? "big" : "small"}`}>
<div className="content">
<h2>{title}</h2>
<p>{definition}</p>
<h3>Example</h3>
<p>{example}</p>
</div>
<img onClick={() => toggleSizeState(!toggleSize)} src="./resize.svg" alt="resize" className="resize"/>
<div className="bookmark">
<UseAnimations
animationKey="bookmark"
size={26}
/>
</div>
</div>
);
}
export default WordContainer;
You could either have a global state management system (redux, or with custom hooks) that you can use to store the icon size.
Or you could simply provide a callback to your component that stores the icon size in a parent component that then feeds it back to your
Something like this:
const [size, setSize] = useState(/* default value */);
render() {
<>
<Sort onSizeToggle={setSize} />
<WordContainer size={size} />
</>
}

Accessing HTML elements inside a React component

I have a React component InputComponent which I cannot edit, and I would like to get a reference to one of its inner divs. (for example for the purpose of focusing on the input field).
const RefsExamplePage = () => {
return (
<div>
<div>
<InputComponent
title="Test component"
></InputComponent>
</div>
</div>
)
}
export default RefsExamplePage;
How do I achieve this?
which I cannot edit
If you can't edit it, the only thing you can do is pass ref to it and hope the InputComponent have refs implemented.
e.g.
const RefsExamplePage = () => {
// use inputRef.current to access the input reference
const inputRef = React.useRef()
return (
<div>
<div>
<InputComponent
ref={inputRef}
title="Test component"
/>
</div>
</div>
)
}
If this doesn't work or give you some error, you will need to modify the InputComponent
If InputComponent doesn't provide ref you can wrap its parent (the div container) then set ref for it:
import React, { useRef } from "react";
const RefsExamplePage = () => {
const container = useRef();
return (
<div>
<div ref={container}>
<InputComponent
title="Test component"
></InputComponent>
</div>
</div>
)
}
export default RefsExamplePage;
Then you can access the child element through the div's ref.
Use useRef() to create a ref to the component itself. This way you can get the components reference and you can use .current property of it to get the underlying DOM:
const RefsExamplePage = () => {
const inputRef = useRef();
const getInput = e => {
// here get the any dom node available
inputRef.current.querySelector('input').focus();
};
return (....
<InputComponent
ref={inputRef}
onClick={getInput}
title="Test component"/> // <---if no child are passed change to self closing
....)
}

Resources