javascript - React Ref没有在表单中获取文本输入字段数据
问题描述
我在自定义输入字段中使用 react Ref,但它没有获取输入内容。
我在 React 类组件中创建了一些 ref 并在表单自定义输入字段 refs 中使用它们。然后我在表单中有一个按钮,它具有“onClick”事件来获取该数据。当我得到“ref.current.value”时,我总是在控制台中不确定
class LandingAfterSignIn extends React.Component {
titleTextFieldRef = React.createRef();
shortDescriptionMetaTextFieldRef = React.createRef();
longDescriptionMetaTextFieldRef = React.createRef();
imageFieldRef = React.
createRef();
webFieldRef = React.createRef();
contactTextFieldRef = React.createRef();
constructor(props) {
super(props);
// we use this to make the card to appear after the page has been rendered
this.state = {
cardAnimaton: "cardHidden",
isLoading: false,
error: null
};
// super(props);
this.state = {
errors: []
};
}
render() {
let image= require("assets/img/landing-bg.jpg") ;
const { classes, ...rest } = this.props;
//let titleTextFieldRef= this.titleTextFieldRef ;
//let shortDescriptionMetaTextFieldRef = this.shortDescriptionMetaTextFieldRef ;
return (
<div
className={classes.pageHeader}
style={{
backgroundImage: "url(" + image + ")",
backgroundSize: "cover",
backgroundPosition: "top center",
width: "100%"
}}
>
<Header
color="transparent"
routes={dashboardRoutes}
brand="StockNap"
rightLinks={<HeaderLinks />}
fixed
changeColorOnScroll={{
height: 400,
color: "white"
}}
{...rest}
/>
<div>
<div className={classes.container}>
<div className={classes.container}>
<GridContainer>
<GridItem xs={12} sm={12} md={6}>
<h1 className={classes.title}>Welcome {firebase.auth().currentUser.displayName} </h1>
<FirebaseDatabaseMutation type="push" path="user_bookmarks">
{({ runMutation }) => (
<form>
<GridContainer>
<GridItem xs={12} sm={12} md={6}>
<CustomInput
labelText="Company Name/Title"
id="titleTextField"
formControlProps={{
fullWidth: true
}}
inputRef={this.titleTextFieldRef}
>
</CustomInput>
</GridItem>
<GridItem xs={12} sm={12} md={6}>
<CustomInput
labelText="short Description"
id="shortDescription"
formControlProps={{
fullWidth: true,
className: classes.textArea
}}
inputRef={this.shortDescriptionMetaTextFieldRef}
/>
</GridItem>
<GridItem xs={12} sm={12} md={6}>
<CustomInput
labelText="long Description"
id="longDescription"
formControlProps={{
fullWidth: true,
className: classes.textArea
}}
inputProps={{
multiline: true,
rows: 2
}}
inputRef={this.longDescriptionMetaTextFieldRef}
/>
</GridItem>
<GridItem xs={12} sm={12} md={6}>
<CustomInput
labelText="contact"
id="contactTextField"
formControlProps={{
fullWidth: true,
}}
inputRef={this.contactTextFieldRef}
/>
</GridItem>
<Button
style={{
width: 50,
height: 50,
alignSelf: "center",
background: "#039BE5",
color: "white"
}}
variant="fab"
type="submit"
onClick={async ev => {
console.log("submit") ;
ev.preventDefault();
ev.stopPropagation();
ev.nativeEvent.stopImmediatePropagation();
const titleTextField = get(
this.titleTextFieldRef,
"current.value",
""
);
const shortDescriptionMetaTextField = get(
this.shortDescriptionMetaTextFieldRef,
"current.value",
""
);
const longDescriptionkMetaTextField = get(
this.longDescriptionMetaTextFieldRef,
"current.value",
""
);
const contactTextField = get(
this.contactTextFieldRef,
"current.value",
""
);
console.log(this.titleTextFieldRef);
console.log(this.shortDescriptionMetaTextFieldRef);
await runMutation({
titleTextField: titleTextField,
shortDescriptionMetaTextField: shortDescriptionMetaTextField,
created_at: firebase.database.ServerValue.TIMESTAMP,
updated_at: firebase.database.ServerValue.TIMESTAMP
});
set(this.titleTextFieldRef, "current.value", "");
set(this.shortDescriptionMetaTextFieldRef, "current.value", "");
}}
>
+
</Button>
</GridContainer>
</form>
)}
</FirebaseDatabaseMutation>
</GridItem>
</GridContainer>
</div>
</div>
</div>
<div className={classNames(classes.main, classes.mainRaised)}>
<div className={classes.container}>
</div>
</div>
<br/>
<Footer />
</div>
);
}
}
我想添加更多信息,customInput 是我希望父母参考的功能组件
function CustomInput({ ...props }) {
const {
classes,
formControlProps,
labelText,
id,
labelProps,
inputProps,
error,
white,
inputRootCustomClasses,
success
} = props;
const labelClasses = classNames({
[" " + classes.labelRootError]: error,
[" " + classes.labelRootSuccess]: success && !error
});
const underlineClasses = classNames({
[classes.underlineError]: error,
[classes.underlineSuccess]: success && !error,
[classes.underline]: true,
[classes.whiteUnderline]: white
});
const marginTop = classNames({
[inputRootCustomClasses]: inputRootCustomClasses !== undefined
});
const inputClasses = classNames({
[classes.input]: true,
[classes.whiteInput]: white
});
var formControlClasses;
if (formControlProps !== undefined) {
formControlClasses = classNames(
formControlProps.className,
classes.formControl
);
} else {
formControlClasses = classes.formControl;
}
return (
<FormControl {...formControlProps} className={formControlClasses}>
{labelText !== undefined ? (
<InputLabel
className={classes.labelRoot + " " + labelClasses}
htmlFor={id}
{...labelProps}
>
{labelText}
</InputLabel>
) : null}
<Input
classes={{
input: inputClasses,
root: marginTop,
disabled: classes.disabled,
underline: underlineClasses
}}
id={id}
{...inputProps}
/>
</FormControl>
);
}
解决方案
来自官方文档:
在典型的 React 数据流中,props 是父组件与其子组件交互的唯一方式。要修改一个孩子,你可以用新的道具重新渲染它。
您的第一个倾向可能是在您的应用程序中使用 refs 来“让事情发生”。如果是这种情况,请花点时间更批判地思考在组件层次结构中应该拥有状态的位置。通常,很明显“拥有”该状态的适当位置位于层次结构中的更高级别。有关此示例,请参阅Lifting State Up指南。
目前,您正在做您不应该做的事情:使用 refs 访问组件方法。这是反模式并使您的代码容易受到您现在遇到的错误的影响。您应该:
- 如果您需要将数据从一个组件传递到另一个组件,请提升状态
- 如果您需要触发操作,请使用像Redux这样的状态容器库
无论哪种方式,我都强烈建议您在任一方向重构您的代码。
推荐阅读
- ios - 视频未在 iOS 上显示,同一页面上的其他视频有效
- reactjs - 从 React 抽象语法生成把手
- amazon-web-services - 新 EC2 未连接到 RDS
- html - 媒体查询在生产与开发中的表现不同
- html - 链接与孩子的大小不同
- sql - 在签出另一项之前签出一项的客户的 SQL 查询
- angular - 如何在 Angular 的应用程序级别设置自动完成“关闭”?
- android - 如何让 Android 10+ 用户从我的应用程序的下载文件夹中导入 zip 文件?
- javascript - Bootstrap V5 & jQuery:再次打开模态框时关闭事件不返回
- r - 是否可以拆分相关框以显示pairplot中两种不同处理的相关值?