Reputation: 1830
I have a form that, on submission displays the results of the form, but more importantly, scrolls to a component that shows the results. I am stuck trying to pass in refs and forward refs. All of the demos I've seen have been of components in the same file. My setup is as follows:
The App.js
holds two components– Form.js
which submits the form and Results.js
which displays the results of the form submission. The Results.js
component is further down the page so I want to scroll to that component once the user clicks enter on the form.
Here is a codesandbox that demonstrates my setup.
Here is the same code on here:
// App.js
import "./styles.css";
import Form from "./Form";
import Results from "./Results";
export default function App() {
return (
<>
<Form />
<Results />
</>
);
}
// Form.js
import { forwardRef, useState } from "react";
const Form = forwardRef(({ onScroll }, ref) => {
const [name, setName] = useState("");
const onSubmit = (e) => {
e.preventDefault();
onScroll();
};
return (
<form onSubmit={onSubmit} className="tall">
<input value={name} onChange={(e) => setName(e.target.value)} />
<button type="submit">Submit</button>
</form>
);
});
export default Form;
// Results.js
import { useRef } from "react";
export default function Results() {
const resultsRef = useRef();
function handleScrollToResults() {
resultsRef.current.scrollIntoView({ behavior: "smooth" });
}
return (
<div onScroll={handleScrollToResults}>
<h1>Results</h1>
</div>
);
}
Upvotes: 13
Views: 20283
Reputation: 13235
Few things to be corrected.
Results
component should forward the ref, not to the Form
component.import { forwardRef } from "react";
const Results = forwardRef((props, ref) => {
return (
<div ref={ref}>
<h1>Results</h1>
</div>
);
});
export default Results;
Form
component should receive the ref to Results
as a prop (resultRef
).import { useState } from "react";
const Form = ({ resultRef }) => {
const [name, setName] = useState("");
const onSubmit = (e) => {
e.preventDefault();
resultRef.current.scrollIntoView({ behavior: "smooth" });
};
return (
<form onSubmit={onSubmit} className="tall">
<input value={name} onChange={(e) => setName(e.target.value)} />
<button type="submit">Submit</button>
</form>
);
};
export default Form;
ref
using useRef
and use it as below. Notice that Form
is using the resultRef
while Results
is instantiating it.import "./styles.css";
import Form from "./Form";
import Results from "./Results";
import { useRef } from "react";
export default function App() {
const resultRef = useRef(null);
return (
<>
<Form resultRef={resultRef} />
<Results ref={resultRef} />
</>
);
}
Upvotes: 13