Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs ForwardRef警告响应钩子窗体与物料UI文本字段_Reactjs_Material Ui_React Hook Form - Fatal编程技术网

Reactjs ForwardRef警告响应钩子窗体与物料UI文本字段

Reactjs ForwardRef警告响应钩子窗体与物料UI文本字段,reactjs,material-ui,react-hook-form,Reactjs,Material Ui,React Hook Form,我正试图用react钩子表单和Material UI的输入构建一个表单(在本例中是我的自定义TextField变体)。虽然表单看起来工作得很好,但在呈现表单时会在控制台中触发一条警告消息 警告:不能为功能组件提供参考。试图 访问此ref将失败。您是想使用React.forwardRef()吗 我正在使用react hook表单的控制器包装我的文本字段(如文档所建议的) 欢迎提出任何建议或解决方案 下面是TextField组件和出现此问题的表单: 组件文本字段 const TextField =

我正试图用react钩子表单和Material UI的输入构建一个表单(在本例中是我的自定义TextField变体)。虽然表单看起来工作得很好,但在呈现表单时会在控制台中触发一条警告消息

警告:不能为功能组件提供参考。试图 访问此ref将失败。您是想使用React.forwardRef()吗

我正在使用react hook表单的控制器包装我的文本字段(如文档所建议的)

欢迎提出任何建议或解决方案

下面是TextField组件和出现此问题的表单:

组件文本字段

const TextField = props => {
    const {
        icon,
        disabled,
        errors,
        helperText,
        id,
        label,
        value,
        name,
        required,
        ...rest
      } = props;

    const classes = useFieldStyles();
    
    return (
        <MuiTextField 
            {...rest}
            name={name}
            label={label}
            value={value || ''}
            required={required}
            disabled={disabled}
            helperText={helperText}
            error={errors}
            variant="outlined" 
            margin="normal" 
            color="primary"
            InputProps={{
                startAdornment: icon,
                classes: {
                    notchedOutline: classes.outline,
                },
            }}
            InputLabelProps={{
                className: classes.inputLabel,
            }}
        />
    )
};

TextField.propTypes = {
    icon: PropTypes.node,
    disabled: PropTypes.bool,
    label: PropTypes.string,
    id: PropTypes.string,
    value: PropTypes.any,
    required: PropTypes.bool,
    helperText: PropTypes.string,
};

export default TextField;
const TextField=props=>{
常数{
偶像
残废
错误,
帮助文字,
身份证件
标签,
价值
名称
必修的,
休息
}=道具;
常量类=useFieldStyles();
返回(
)
};
TextField.propTypes={
图标:PropTypes.node,
禁用:PropTypes.bool,
标签:PropTypes.string,
id:PropTypes.string,
值:PropTypes.any,
必需:PropTypes.bool,
helperText:PropTypes.string,
};
导出默认文本字段;
组件登录表单

const LoginForm = () => {
    const { handleSubmit, errors, control } = useForm();
    const onSubmit = values => console.log(values);

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <Typography variant="h5" color="primary" gutterBottom>
                Login
            </Typography>

            <Box py={3} height="100%" display="flex" flexDirection="column">
                <Controller
                    as={TextField}
                    label="Username"
                    name="username"
                    control={control}
                    errors={errors}
                    required
                />

                <Controller
                    as={TextField}
                    label="Password"
                    type="password"
                    name="password"
                    control={control}
                    errors={errors}
                    required
                />

                <Link>
                    Forgot your password?
                </Link>
            </Box>

            <Button variant="contained" color="primary" fullWidth type="submit">
                Submit
            </Button>
        </form>
    )
};
const LoginForm=()=>{
const{handleSubmit,errors,control}=useForm();
const onSubmit=values=>console.log(值);
返回(
登录
忘记密码了?
提交
)
};

官方文件建议的警告完全正确,它认为您没有触及功能部件

无法为功能组件提供引用,因为它们没有实例

如果您希望允许人们引用您的函数组件,可以使用
forwardRef
(可能与
useImperialiveHandle
结合使用),也可以将组件转换为类

但是,您可以在函数组件内使用
ref
属性,只要您引用DOM元素或类组件,如下所示:

function CustomTextInput(props) {
  // textInput must be declared here so the ref can refer to it
  const textInput = useRef(null);
  
  function handleClick() {
    textInput.current.focus();
  }

  return (
    <div>
      <input
        type="text"
        ref={textInput} />
      <input
        type="button"
        value="Focus the text input"
        onClick={handleClick}
      />
    </div>
  );
}

功能自定义文本输入(道具){
//textInput必须在此处声明,以便ref可以引用它
const textInput=useRef(null);
函数handleClick(){
textInput.current.focus();
}
返回(
);
}

尝试使用
控制器的render prop,而不是
作为
,因为TextField公开的ref实际上被称为inputRef,而
控制器
正试图访问
ref

import React, { useState } from "react";
import ReactDOM from "react-dom";
import { useForm, Controller } from "react-hook-form";
import Header from "./Header";
import { TextField, ThemeProvider, createMuiTheme } from "@material-ui/core";
import "react-datepicker/dist/react-datepicker.css";

import "./styles.css";
import ButtonsResult from "./ButtonsResult";

let renderCount = 0;

const theme = createMuiTheme({
  palette: {
    type: "dark"
  }
});

const defaultValues = {
  TextField: "",
  TextField1: ""
};

function App() {
  const { handleSubmit, reset, control } = useForm({ defaultValues });
  const [data, setData] = useState(null);
  renderCount++;

  return (
    <ThemeProvider theme={theme}>
      <form onSubmit={handleSubmit((data) => setData(data))} className="form">
        <Header renderCount={renderCount} />
        <section>
          <label>MUI TextField</label>
          <Controller
            render={(props) => (
              <TextField
                value={props.value}
                onChange={props.onChange}
                inputRef={props.ref}
              />
            )}
            name="TextField"
            control={control}
            rules={{ required: true }}
          />
        </section>

        <section>
          <label>MUI TextField</label>
          <Controller
            render={(props) => (
              <TextField
                value={props.value}
                onChange={props.onChange}
                inputRef={props.ref}
              />
            )}
            name="TextField1"
            control={control}
            rules={{ required: true }}
          />
        </section>

        <ButtonsResult {...{ data, reset, defaultValues }} />
      </form>
    </ThemeProvider>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

import React,{useState}来自“React”;
从“react dom”导入react dom;
从“react hook form”导入{useForm,Controller};
从“/Header”导入标题;
从“@material ui/core”导入{TextField,ThemeProvider,createMuiTheme};
导入“react datepicker/dist/react datepicker.css”;
导入“/styles.css”;
从“/ButtonsResult”导入ButtonsResult;
设renderCount=0;
const theme=createMuiTheme({
调色板:{
类型:“暗”
}
});
常量默认值={
文本字段:“”,
TextField1:“
};
函数App(){
const{handleSubmit,reset,control}=useForm({defaultValues});
const[data,setData]=useState(null);
renderCount++;
返回(
setData(data))}className=“form”>
MUI文本字段
(
)}
name=“TextField”
control={control}
规则={required:true}
/>
MUI文本字段
(
)}
name=“TextField1”
control={control}
规则={required:true}
/>
);
}
const rootElement=document.getElementById(“根”);

render(

谢谢你,比尔,我后来也采用了这种方法,这确实避免了使用Ref的困难。我还发现以前版本的react钩子表单(v6.0.8)使用“as”道具时没有这种行为是的,这是正确的。我们在6.10.0中引入了额外的
ref
prop来改进焦点管理。