I have two components. A parent and a child.
Inside the parent component I have a button. If the user clicks on that button I want to do a ScrollIntoView to another button inside the child component.
I guess I want to define a reference to the childs button a so that I inside the parent button onClick can do a:
ref.scrollIntoView({block: 'end', behavior: 'smooth'});
that will scroll to the button in the child component.
Here is a minified example:
ParentComponent.jsx
import React, {useRef} from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = props => {
const childReference = useRef(null);
const onClick = () => {
childReference.scrollIntoView({block: 'end', behavior: 'smooth'});
}
return (
<>
<...some other components>
<Button onClick={onClick}>Click me to be forwarded</Button>
<ChildComponent ref={childReference}/>
</>
);
};
ChildComponent.jsx
import React from 'react';
const ChildComponent = (props, ref) => {
const { name, value, description } = props;
return (
<...some other components>
<Button ref={ref}>You should be forwarded to me</Button>
);
};
ChildComponent.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.number,
description: PropTypes.string,
};
ChildComponent.defaultProps = {
value: 0,
description: '',
};
export default React.forwardRef(ChildComponent);
I know the above code doesn't work, it was just to illustrate what I am trying to achieve.
I have really tried every other solution I have been able to find by Googling and they all seem so easy, but none of them seem to work for my use case. I have tried using forwardRef as well, but that also doesn't fix it for me.
UPDATE
I guess I was a little vague on what's not working. I've been getting a lot of different error messages with the implementation.
The following is one of them:
Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
Solution
Okay. I thought I'd assemble the pieces here with the solution provided by @Vencovsky.
This is the full implementation with the two example components seen in the question:
ParentComponent.jsx
import React, { useRef } from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = props => {
const childReference = useRef(null);
const scrollIntoView = () => {
childReference.current.scrollIntoView({block: 'center', inline: 'center', behavior: 'smooth'});
}
return (
<>
<...some other component>
<Button onClick={scrollIntoView}>Click me to be forwarded</Button>
<ChildComponent ref={childReference}
</>
);
};
export default ParentComponent;
ChildComponent.jsx
import React, {forwardRef} from 'react';
import PropTypes from 'prop-types';
const ChildComponent = forwardRef((props, ref) => {
const { name, value, description } = props;
return(
<>
<...some other components>
<Button ref={ref}>You should be forwarded to me</Button>
</>
);
});
ChildComponent.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.number,
description: PropTypes.string,
};
ChildComponent.defaultProps = {
value: 0,
description: '',
};
export default ChildComponent;
Button
as well. – Druce