Accessing HTML elements inside a React component - reactjs

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
....)
}

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])

How do you reference a div from a separate JSX file and send it to another JSX file

So I have app.jsx which calls up all my other JSX files.
This way I have each component organized in its own file.
I would like to navigate to each section of the website (all on one page just different areas). The only issue is I can't seem to reference where
I want to go to. I thought if I referenced the imported jsx file it would get its DOM elements. But that's not working. What seems to work is if I have a div directly being referenced in the same App.jsx file. But I need to get the child div element.
function App() {
const aboutmeOnClickRef = useRef(null);
const portfolioOnClickRef = useRef(null);
const employmentOnClickRef = useRef(null);
const educationOnClickRef = useRef(null);
const letschatOnClickRef = useRef(null);
return (
<div className="app">
<Topbar
aboutmeOnClickRef={aboutmeOnClickRef}
portfolioOnClickRef={portfolioOnClickRef}
employmentOnClickRef={employmentOnClickRef}
educationOnClickRef={educationOnClickRef}
letschatOnClickRef={letschatOnClickRef}
/>
<div className="sections">
<Intro />
<DisplayAboutMe ref={aboutmeOnClickRef} />
<Portfolio ref={portfolioOnClickRef} />
<Employment ref={employmentOnClickRef} />
<Education ref={educationOnClickRef} />
<LetsChat ref={letschatOnClickRef} />
</div>
</div>
);
}
//This is what I want to do, but doesn't work
//const DisplayAboutMe = React.forwardRef((props, ref) => <AboutMe ref={ref} />);
//This one works but creates a whole new div and doesn't get my jsx file
const DisplayAboutMe = React.forwardRef((props, ref) => <div ref={ref} />);
AboutMe.jsx
import React from "react";
import styles from "./aboutme.module.scss";
export default function AboutMe() {
return (
<div className={styles.aboutme} id={styles.aboutme}></div>
);
}
By default, refs to function components don't do anything. You need to use forwardRef to tell react which dom element you want the ref to point to. Currently, your about me component doesn't do this. Here's what it might look like:
import React from "react";
import styles from "./aboutme.module.scss";
const AboutMe = React.forwardRef((props, ref) => {
return (
<div ref={ref} className={styles.aboutme} id={styles.aboutme}></div>
);
});
export default AboutMe
With the above change, you shouldn't need DisplayAboutMe. App can render an <AboutMe> and pass in a ref, and the ref will be assigned the div that's inside AboutMe.
function App() {
const aboutmeOnClickRef = useRef(null);
// ...
<div className="sections">
<Intro />
<AboutMe ref={aboutmeOnClickRef} />
</div>
// ...
}
// In topBar:
function TopBar(props) {
return (
// ...
<a onClick={() => { props.aboutMeOnClickRef.current.scrollIntoView() }}/>
// ...
)
}

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

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>
);
}

React trying to call child (useRef) function in a functional component

I have a sub component that is generating and displaying a random number.
I'm trying to control it from the parent.
but the ref current is null.
How can I call a child function from a parent in a functional component
https://codesandbox.io/s/busy-joliot-85yom
function App() {
const child = useRef();
const generate = () => child.current.generate();
return (
<div className="App">
<br />
<Child ref={child}></Child><br />
<button onClick={generate}>regenerate from parent (Not working)</button>
</div>
);
}
function Child(props){
const [number, setNumber] = useState(0);
const generate = () => setNumber(Math.round(Math.random() * 10));
return <div>{number} <br /> <button onClick={generate}>regenerate from child</button></div>;
}
Thanks
You cant use ref property in functional component, but you could handle any ref object by yourself, just don't call it "ref", react doesn't like it.
Check my example

Ist there a way to pass data from child to parent using Hooks?

As an absolute newbie to React, I'd like to pass data from a child to parent component. But if I look for this question, I always find the "old" way using "state" and "callback" functions. See for example this article: https://medium.com/#ruthmpardee/passing-data-between-react-components-103ad82ebd17
Since all the guides use the traditional way, I'm very confused because they look so different from what I know. For example, instead of using "this.state" in the constructor, I use the useState() Hook.
Is there any way or maybe Hook I don't see that makes it possible to pass data from a child to a parent component?
Imagine that you have a parent component App that has the logic for handling the submit (could be any other kind of logic) of a form that is a child component of App.
The ChildForm has a local state to store its inputValue.
When you click the submit function, it will call a function onSubmit from the parent App and it will pass along its inputValue (you can pass any other value that it's present inside the component) to be processed and submitted, in this example.
So the gist of it, is:
Send a function from the parent to the child as props
The child will call that function sending some data as parameters
That function will handle the data and can trigger some action from the parent, for example
See snippet below:
function App() {
function onSubmit(formState) {
console.log('I will submit my ChildForm Input State: ' + formState);
}
return(
<ChildForm
onSubmit={onSubmit}
/>
);
}
function ChildForm(props) {
const [inputValue,setInputValue] = React.useState('');
function onChange() {
setInputValue(event.target.value);
}
return(
<React.Fragment>
<div>I am ChildForm</div>
<input type='text' value={inputValue} onChange={onChange}/>
<button onClick={()=>props.onSubmit(inputValue)}>Click to Submit through parent App</button>
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
There is no difference in flow between Functional and Class Component. You can update the value of the parent by passing the function with props and using it at the child.
parent.js
import React, {useState} from 'react';
const Parent = () => {
const [counter, setCounter] = useState(0);
return (
<Child updateCounter={setCounter}>
</Child>
)
}
child.js
const Child = (props) => {
const {updateCounter} = props;
return (
<button onClick={() => updateCounter(some value)}>
</button>
)
}
You will need to pass functions as props from the parent component to the child in order to pass data up the tree
function Child({ num, onNumClick }) {
return <span onClick={() => onNumClick(num)}>{num}</span>;
}
function Parent() {
const [numList] = useState([1, 2, 3, 4, 5]);
const [clickedItem, setClickedItem] = useState(null);
const onNumClick = num => setClickedItem(num);
return (
<div className="App">
{numList.map(n => (
<Child num={n} onNumClick={onNumClick} />
))}
{clickedItem && <p>You clicked on {clickedItem}</p>}
</div>
);
}
sandbox

Resources