我正在将useRef实现到我的项目中。我有一个包含可点击部分的表单。单击后打开表格。我正在使用Reactstrap Collapse来显示/隐藏表单。我需要能够打开表单并显示需要填写的部分,但是,一旦单击该部分,scrollIntoView将无法工作,直到再次打开并关闭表单。我很沮丧在console.log(formRef)
中,引用按预期返回了我希望在后续调用中滚动到视口顶部的组件。我的猜测是,formRef
首先被初始化为null
,因此对ref的初始调用不起作用。但是,一旦知道了ref,后续的调用就会起作用。我不确定该怎么做。
如果我需要提供一个示例,请告诉我。我希望这只是一个初始化问题。
表格
import React, { useRef, useContext, useEffect } from "react";
import {
FormQuestionsContext,
FormAnswersContext,
ExpandedSectionContext,
} from "../../Store";
import SectionHeader from "../SectionHeader";
import ImageUploader from "../CommentsSection";
import Ratings from "../Ratings";
import { Collapse, Button, CardBody, Card } from "reactstrap";
import FontAwesome from "react-fontawesome";
import styles from "./bedthreeform.module.css";
function BedThreeForm({ Name }) {
const formRef = useRef(null); //useRef Initialization
const [expandedSection, setExpandedSection] = useContext(
ExpandedSectionContext
);
const [formQuestions, setFormQuestions] = useContext(FormQuestionsContext);
const [formAnswers, setFormAnswers] = useContext(FormAnswersContext);
const array = formQuestions.bedthree;
const onChange = (e, name) => {
const { value } = e.target;
setFormAnswers((state) => ({
...state,
[Name]: { ...state[Name], [name]: value },
}));
};
//! The function I use when I want to tell useRef to scrollIntoView
const handleOpen = () => {
expandedSection === Name
? setExpandedSection("")
: setExpandedSection(Name);
formRef.current.scrollIntoView();
};
const answeredQuestions = formAnswers.bedthree
? Object.keys(formAnswers.bedthree)
: null;
console.log(formRef);
return (
<div>
<Button
className={styles["CollapseBtn"]}
onClick={handleOpen} //Calling the function here
style={
answeredQuestions &&
answeredQuestions.length === formQuestions.bedthree.length
? {
color: "white",
":focus": {
backgroundColor: "#02BD43",
},
backgroundColor: "#02BD43",
marginBottom: "1rem",
width: "100%",
}
: answeredQuestions &&
answeredQuestions.length !== formQuestions.bedthree.length
? {
color: "white",
":focus": {
backgroundColor: "#bd0202",
},
backgroundColor: "#bd0202",
marginBottom: "1rem",
width: "100%",
}
: {
":focus": {
backgroundColor: "#fafafa",
},
marginBottom: "1rem",
width: "100%",
}
}
>
<p>BEDROOM #3 INSPECTION</p>
<FontAwesome
className="super-crazy-colors"
name="angle-up"
rotate={expandedSection === Name ? null : 180}
size="lg"
style={{
marginTop: "5px",
textShadow: "0 1px 0 rgba(0, 0, 0, 0.1)",
}}
/>
</Button>
<Collapse
className={styles["Collapse"]}
isOpen={expandedSection === Name}
>
<Card>
<CardBody>
{array ? (
<div>
<SectionHeader title="Bedroom #3 Inspection" name={Name} />
<div
ref={formRef}
className={styles["BedroomThreeFormWrapper"]}
id="bedroom-three-form"
>
{array.map((question, index) => {
const selected =
formAnswers[Name] && formAnswers[Name][question]
? formAnswers[Name][question]
: "";
return (
<div className={styles["CheckboxWrapper"]} key={index}>
<h5>{question}</h5>
<Ratings
section={Name}
question={question}
onChange={onChange}
selected={selected}
/>
</div>
);
})}
</div>
{!answeredQuestions ? (
""
) : (
<Button
onClick={(e) => e.preventDefault()}
style={
!answeredQuestions ||
(answeredQuestions &&
answeredQuestions.length !==
formQuestions.bedthree.length)
? {
backgroundColor: "#bd0202",
color: "white",
pointerEvents: "none",
}
: {
backgroundColor: "#02BD43",
color: "white",
pointerEvents: "none",
}
}
>
{!answeredQuestions ||
(answeredQuestions &&
answeredQuestions.length !==
formQuestions.bedthree.length)
? "Incomplete"
: "Complete"}
</Button>
)}
<br />
<ImageUploader name="bedthree" title={"Bedroom #3"} />
</div>
) : (
<div></div>
)}
</CardBody>
</Card>
</Collapse>
</div>
);
}
export default BedThreeForm;
CodeSandbox Stripped Form不能按预期工作,但这是剥离的代码。
更新,我愿意接受一些绕过此方法或其他替代方法的建议。我不确定为什么只在后续通话中使用它。
答案 0 :(得分:0)
看看这些行:
<CardBody>
{array ? (
...
<div
ref={formRef}
...
仅在定义array
的情况下,才会评估此(虚拟)域。如果您想让自己的formRef
始终指向dom,则必须将其从条件中删除。
答案 1 :(得分:0)
我已经解决了这个问题,问题是在尚未加载折叠中的内容时调用它,Reactstrap具有属性onEntered
,该属性基本上在设置后会尽快运行该函数崩溃完全打开了。我发现的示例是here。此外,通过在Reactstrap组件上设置属性innerRef
,我可以像使用ref
的常规组件一样操作它。