首页 > 解决方案 > 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>
  );
}

标签: javascriptreactjsreact-redux

解决方案


来自官方文档

在典型的 React 数据流中,props 是父组件与其子组件交互的唯一方式。要修改一个孩子,你可以用新的道具重新渲染它。

您的第一个倾向可能是在您的应用程序中使用 refs 来“让事情发生”。如果是这种情况,请花点时间更批判地思考在组件层次结构中应该拥有状态的位置。通常,很明显“拥有”该状态的适当位置位于层次结构中的更高级别。有关此示例,请参阅Lifting State Up指南。

目前,您正在做您不应该做的事情:使用 refs 访问组件方法。这是反模式并使您的代码容易受到您现在遇到的错误的影响。您应该:

  • 如果您需要将数据从一个组件传递到另一个组件,请提升状态
  • 如果您需要触发操作,请使用像Redux这样的状态容器库

无论哪种方式,我都强烈建议您在任一方向重构您的代码。


推荐阅读