使用element-react UI组件,我一直在努力解决由于在
中包装表单而引起的问题& lt; UserContext.Consumer>
& lt;/UserContext.Consumer>
我得到错误信息:
Error: Function components cannot have string refs. We recommend using useRef() instead.
类的内容是从这里复制/粘贴的,在验证的标题下。如果我不使用UserContext部分,这段代码在我的应用中工作得很好。UserContext在App.js中声明为
export const UserContext = React.createContext();
你能告诉我如何重写这个,这样我就可以使用UserContext,并有字段验证与元素反应请。
import React, { Component } from 'react';
import { i18n, Dialog, Button, Notification, Radio, Layout, DatePicker, Form,
Select,Input,TimePicker,Switch,Checkbox } from "element-react";
import { UserContext } from '../App';
class MyPetsPage extends Component {
constructor(props) {
super(props);
this.state = {
form: {
name: '',
region: '',
date1: null,
date2: null,
delivery: false,
type: [],
resource: '',
desc: ''
},
rules: {
name: [
{ required: true, message: 'Please input Activity name', trigger: 'blur' }
],
region: [
{ required: true, message: 'Please select Activity zone', trigger: 'change' }
],
date1: [
{ type: 'date', required: true, message: 'Please pick a date', trigger: 'change' }
],
date2: [
{ type: 'date', required: true, message: 'Please pick a time', trigger: 'change' }
],
type: [
{ type: 'array', required: true, message: 'Please select at least one activity type', trigger:
'change' }
],
resource: [
{ required: true, message: 'Please select activity resource', trigger: 'change' }
],
desc: [
{ required: true, message: 'Please input activity form', trigger: 'blur' }
]
}
};
}
handleSubmit(e) {
e.preventDefault();
this.refs.form.validate((valid) => {
if (valid) {
alert('submit!');
} else {
console.log('error submit!!');
return false;
}
});
}
handleReset(e) {
e.preventDefault();
this.refs.form.resetFields();
}
onChange(key, value) {
this.setState({
form: Object.assign({}, this.state.form, { [key]: value })
});
}
render() {
return ( <UserContext.Consumer>
{({user}) => <>
<Form ref="form" className="en-US" model={this.state.form} rules={this.state.rules}
labelWidth="120">
<Form.Item label="Activity name" prop="name">
<Input value={this.state.form.name} onChange={this.onChange.bind(this, 'name')}></Input>
</Form.Item>
<Form.Item label="Activity zone" prop="region">
<Select value={this.state.form.region} placeholder="Activity zone" onChange=
{this.onChange.bind(this, 'region')}>
<Select.Option label="Zone 1" value="shanghai"></Select.Option>
<Select.Option label="Zone 2" value="beijing"></Select.Option>
</Select>
</Form.Item>
<Form.Item label="Activity time" required={true}>
<Layout.Col span="11">
<Form.Item prop="date1" labelWidth="0px">
<DatePicker
value={this.state.form.date1}
placeholder="Pick a date"
onChange={this.onChange.bind(this, 'date1')}
/>
</Form.Item>
</Layout.Col>
<Layout.Col className="line" span="2">-</Layout.Col>
<Layout.Col span="11">
<Form.Item prop="date2" labelWidth="0px">
<TimePicker
value={this.state.form.date2}
selectableRange="18:30:00 - 20:30:00"
placeholder="Pick a time"
onChange={this.onChange.bind(this, 'date2')}
/>
</Form.Item>
</Layout.Col>
</Form.Item>
<Form.Item label="Instant delivery" prop="delivery">
<Switch value={this.state.form.delivery} onChange={this.onChange.bind(this, 'delivery')}>
</Switch>
</Form.Item>
<Form.Item label="Activity type" prop="type">
<Checkbox.Group value={this.state.form.type} onChange={this.onChange.bind(this, 'type')}>
<Checkbox label="Online activities" name="type"></Checkbox>
<Checkbox label="Promotion activities" name="type"></Checkbox>
<Checkbox label="Offline activities" name="type"></Checkbox>
<Checkbox label="Simple brand exposure" name="type"></Checkbox>
</Checkbox.Group>
</Form.Item>
<Form.Item label="Resources" prop="resource">
<Radio.Group value={this.state.form.resource} onChange={this.onChange.bind(this, 'resource')}>
<Radio value="Sponsor"></Radio>
<Radio value="Venue"></Radio>
</Radio.Group>
</Form.Item>
<Form.Item label="Activity form" prop="desc">
<Input type="textarea" value={this.state.form.desc} onChange={this.onChange.bind(this, 'desc')}>
</Input>
</Form.Item>
<Form.Item>
<Button type="primary" onClick={this.handleSubmit.bind(this)}>Create</Button>
<Button onClick={this.handleReset.bind(this)}>Reset</Button>
</Form.Item>
</Form>
</>} </UserContext.Consumer>
)
}
}
export default MyPetsPage;
就像错误信息告诉你的那样:
函数组件不能有字符串引用
既然您已经创建了一个基于类的组件,那么您可以使用React.createRef
来创建您的ref
:
constructor(props) {
super(props);
// ...
this.form = React.createRef();
}
现在不用这个:
<Form ref="form"> // ...
这样做:
<Form ref={this.form}> // ...
现在您可以使用form
ref调用validate
函数,如下所示:
this.form.current.validate(...)
完整的示例:
import React, { Component } from "react";
import { useState, useRef, useCallback } from "react";
import {
i18n,
Dialog,
Button,
Notification,
Radio,
Layout,
DatePicker,
Form,
Select,
Input,
TimePicker,
Switch,
Checkbox,
} from "element-react";
import "element-theme-default";
const UserContext = React.createContext("user");
class MyPetsPage extends Component {
constructor(props) {
super(props);
this.state = {
form: {
name: "",
region: "",
date1: null,
date2: null,
delivery: false,
type: [],
resource: "",
desc: "",
},
rules: {
name: [
{
required: true,
message: "Please input Activity name",
trigger: "blur",
},
],
region: [
{
required: true,
message: "Please select Activity zone",
trigger: "change",
},
],
date1: [
{
type: "date",
required: true,
message: "Please pick a date",
trigger: "change",
},
],
date2: [
{
type: "date",
required: true,
message: "Please pick a time",
trigger: "change",
},
],
type: [
{
type: "array",
required: true,
message: "Please select at least one activity type",
trigger: "change",
},
],
resource: [
{
required: true,
message: "Please select activity resource",
trigger: "change",
},
],
desc: [
{
required: true,
message: "Please input activity form",
trigger: "blur",
},
],
},
};
this.form = React.createRef();
}
handleSubmit(e) {
e.preventDefault();
this.form.current.validate((valid) => {
if (valid) {
alert("submit!");
} else {
console.log("error submit!!");
return false;
}
});
}
handleReset(e) {
e.preventDefault();
this.form.current.resetFields();
}
onChange(key, value) {
this.setState({
form: Object.assign({}, this.state.form, { [key]: value }),
});
}
render() {
return (
<UserContext.Consumer>
{(value) => (
<>
<Form
ref={this.form}
className="en-US"
model={this.state.form}
rules={this.state.rules}
labelWidth="120"
>
<Form.Item label="Activity name" prop="name">
<Input
value={this.state.form.name}
onChange={this.onChange.bind(this, "name")}
></Input>
</Form.Item>
<Form.Item label="Activity zone" prop="region">
<Select
value={this.state.form.region}
placeholder="Activity zone"
onChange={this.onChange.bind(this, "region")}
>
<Select.Option
label="Zone 1"
value="shanghai"
></Select.Option>
<Select.Option label="Zone 2" value="beijing"></Select.Option>
</Select>
</Form.Item>
<Form.Item label="Activity time" required={true}>
<Layout.Col span="11">
<Form.Item prop="date1" labelWidth="0px">
<DatePicker
value={this.state.form.date1}
placeholder="Pick a date"
onChange={this.onChange.bind(this, "date1")}
/>
</Form.Item>
</Layout.Col>
<Layout.Col className="line" span="2">
-
</Layout.Col>
<Layout.Col span="11">
<Form.Item prop="date2" labelWidth="0px">
<TimePicker
value={this.state.form.date2}
selectableRange="18:30:00 - 20:30:00"
placeholder="Pick a time"
onChange={this.onChange.bind(this, "date2")}
/>
</Form.Item>
</Layout.Col>
</Form.Item>
<Form.Item label="Instant delivery" prop="delivery">
<Switch
value={this.state.form.delivery}
onChange={this.onChange.bind(this, "delivery")}
></Switch>
</Form.Item>
<Form.Item label="Activity type" prop="type">
<Checkbox.Group
value={this.state.form.type}
onChange={this.onChange.bind(this, "type")}
>
<Checkbox label="Online activities" name="type"></Checkbox>
<Checkbox label="Promotion activities" name="type"></Checkbox>
<Checkbox label="Offline activities" name="type"></Checkbox>
<Checkbox
label="Simple brand exposure"
name="type"
></Checkbox>
</Checkbox.Group>
</Form.Item>
<Form.Item label="Resources" prop="resource">
<Radio.Group
value={this.state.form.resource}
onChange={this.onChange.bind(this, "resource")}
>
<Radio value="Sponsor"></Radio>
<Radio value="Venue"></Radio>
</Radio.Group>
</Form.Item>
<Form.Item label="Activity form" prop="desc">
<Input
type="textarea"
value={this.state.form.desc}
onChange={this.onChange.bind(this, "desc")}
></Input>
</Form.Item>
<Form.Item>
<Button type="primary" onClick={this.handleSubmit.bind(this)}>
Create
</Button>
<Button onClick={this.handleReset.bind(this)}>Reset</Button>
</Form.Item>
</Form>
</>
)}
</UserContext.Consumer>
);
}
}
const App = () => {
return (
<div className="App">
<UserContext.Provider value="user">
<MyPetsPage />
</UserContext.Provider>
</div>
);
};
此时它将工作,但您仍然会在控制台中看到关于字符串refs的错误。这是因为element-react
实际上也使用string-refs
。