我正在尝试在反应中实现 menuitem 但出现错误
I am trying to implement menuitem in react but getting error
- 我正在使用 MenuItem 在 React 中实现下拉菜单。
- 我也导入了包然后我也遇到了 运行 服务器时的错误。
- 我尝试寻找解决方案,但没有找到解决问题的确切方法。
- 或者有没有其他方法可以实现同样的功能?
- 我想在下拉菜单 "User" 和 "Admin" 下有 2 个选项,因此在注册时用户将 select 他的角色。
import React, { Component } from "react";
import { Link, withRouter } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { registerUser } from "../../actions/authActions";
import classnames from "classnames";
import MenuItem from '@material-ui/core/MenuItem';
class Register extends Component {
constructor() {
super();
this.state = {
name: "",
email: "",
password: "",
password2: "",
mobile: "",
errors: {}
};
}
componentDidMount() {
// If logged in and user navigates to Register page, should redirect them to dashboard
if (this.props.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
onChange = e => {
this.setState({ [e.target.id]: e.target.value });
};
onSubmit = e => {
e.preventDefault();
const newUser = {
name: this.state.name,
email: this.state.email,
password: this.state.password,
password2: this.state.password2,
mobile: this.state.mobile
};
this.props.registerUser(newUser, this.props.history);
};
render() {
const { errors } = this.state;
return (
<div className="container">
<div className="row">
<div className="col s8 offset-s2">
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<h4>
<b>Register</b>
</h4>
<p className="grey-text text-darken-1">
Already have an account? <Link to="/">Log in</Link>
</p>
</div>
<form noValidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.name}
error={errors.name}
id="name"
type="text"
className={classnames("", {
invalid: errors.name
})}
/>
<label htmlFor="name">Name</label>
<span className="red-text">{errors.name}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("", {
invalid: errors.email
})}
/>
<label htmlFor="email">Email</label>
<span className="red-text">{errors.email}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password}
error={errors.password}
id="password"
type="password"
className={classnames("", {
invalid: errors.password
})}
/>
<label htmlFor="password">Password</label>
<span className="red-text">{errors.password}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password2}
error={errors.password2}
id="password2"
type="password"
className={classnames("", {
invalid: errors.password2
})}
/>
<label htmlFor="password2">Confirm Password</label>
<span className="red-text">{errors.password2}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.mobile}
error={errors.mobile}
id="mobile"
type="text"
className={classnames("", {
invalid: errors.mobile
})}
/>
<label htmlFor="mobile">Mobile No.</label>
<span className="red-text">{errors.mobile}</span>
</div>
<Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick}>
Open Menu
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
type="submit"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
>
Create
</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
Register.propTypes = {
registerUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(
mapStateToProps,
{ registerUser }
)(withRouter(Register));
下面的问题是 handleClose 和 anchorEl 属性。
我认为您可能是从 material 站点复制的。
你复制的例子是 functional component 在反应中你正在使用 class component.
Material 站点有带功能组件的演示。你可以检查你复制的代码源
https://material-ui.com/components/menus/
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
将它更新到 class 级别 anchorEl 和 handleClose 它会起作用。
演示 link material 站点的功能菜单。
检查 demo.js 查看 anchorEL 和 handleclose 并在您的逻辑中实现它
https://codesandbox.io/s/sm1zv?file=/demo.js
首先,Button
和 Menu
没有定义,所以导入它们:
import Button from '@material-ui/core/Button';
import Menu from '@material-ui/core/Menu';
接下来,anchorEl
、handleClick
、handleClose
未定义
- 您可以使用参考
anchorEl
:
class Register extends Component {
constructor() {
super();
this.state = {
name: "",
email: "",
password: "",
password2: "",
mobile: "",
errors: {},
open: false
};
this.menuRef = React.createRef();
}
...
- 接下来,添加
handleClick
和handleClose
方法:
handleClose = () => {
this.setState({
open: false
});
};
handleClick = () => {
this.setState({
open: true
});
};
还要确保将 state.open: false
添加到构造函数中。
- 最后,更改
Button
和 Menu
标记以使用新定义的属性:
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={this.handleClick}
>
Open Menu
</Button>
<Menu
id="simple-menu"
ref={this.menuRef}
anchorEl={this.menuRef}
keepMounted
open={this.state.open}
onClose={this.handleClose}
>
<MenuItem onClick={this.handleClose}>Profile</MenuItem>
<MenuItem onClick={this.handleClose}>My account</MenuItem>
<MenuItem onClick={this.handleClose}>Logout</MenuItem>
</Menu>
Here's a demo的Menu
开闭,去掉了react-router
的功能
- 我正在使用 MenuItem 在 React 中实现下拉菜单。
- 我也导入了包然后我也遇到了 运行 服务器时的错误。
- 我尝试寻找解决方案,但没有找到解决问题的确切方法。
- 或者有没有其他方法可以实现同样的功能?
- 我想在下拉菜单 "User" 和 "Admin" 下有 2 个选项,因此在注册时用户将 select 他的角色。
import React, { Component } from "react";
import { Link, withRouter } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { registerUser } from "../../actions/authActions";
import classnames from "classnames";
import MenuItem from '@material-ui/core/MenuItem';
class Register extends Component {
constructor() {
super();
this.state = {
name: "",
email: "",
password: "",
password2: "",
mobile: "",
errors: {}
};
}
componentDidMount() {
// If logged in and user navigates to Register page, should redirect them to dashboard
if (this.props.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
onChange = e => {
this.setState({ [e.target.id]: e.target.value });
};
onSubmit = e => {
e.preventDefault();
const newUser = {
name: this.state.name,
email: this.state.email,
password: this.state.password,
password2: this.state.password2,
mobile: this.state.mobile
};
this.props.registerUser(newUser, this.props.history);
};
render() {
const { errors } = this.state;
return (
<div className="container">
<div className="row">
<div className="col s8 offset-s2">
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<h4>
<b>Register</b>
</h4>
<p className="grey-text text-darken-1">
Already have an account? <Link to="/">Log in</Link>
</p>
</div>
<form noValidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.name}
error={errors.name}
id="name"
type="text"
className={classnames("", {
invalid: errors.name
})}
/>
<label htmlFor="name">Name</label>
<span className="red-text">{errors.name}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("", {
invalid: errors.email
})}
/>
<label htmlFor="email">Email</label>
<span className="red-text">{errors.email}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password}
error={errors.password}
id="password"
type="password"
className={classnames("", {
invalid: errors.password
})}
/>
<label htmlFor="password">Password</label>
<span className="red-text">{errors.password}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password2}
error={errors.password2}
id="password2"
type="password"
className={classnames("", {
invalid: errors.password2
})}
/>
<label htmlFor="password2">Confirm Password</label>
<span className="red-text">{errors.password2}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.mobile}
error={errors.mobile}
id="mobile"
type="text"
className={classnames("", {
invalid: errors.mobile
})}
/>
<label htmlFor="mobile">Mobile No.</label>
<span className="red-text">{errors.mobile}</span>
</div>
<Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick}>
Open Menu
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
type="submit"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
>
Create
</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
Register.propTypes = {
registerUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(
mapStateToProps,
{ registerUser }
)(withRouter(Register));
下面的问题是 handleClose 和 anchorEl 属性。 我认为您可能是从 material 站点复制的。 你复制的例子是 functional component 在反应中你正在使用 class component.
Material 站点有带功能组件的演示。你可以检查你复制的代码源 https://material-ui.com/components/menus/
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
将它更新到 class 级别 anchorEl 和 handleClose 它会起作用。
演示 link material 站点的功能菜单。 检查 demo.js 查看 anchorEL 和 handleclose 并在您的逻辑中实现它 https://codesandbox.io/s/sm1zv?file=/demo.js
首先,Button
和 Menu
没有定义,所以导入它们:
import Button from '@material-ui/core/Button';
import Menu from '@material-ui/core/Menu';
接下来,anchorEl
、handleClick
、handleClose
未定义
- 您可以使用参考
anchorEl
:
class Register extends Component {
constructor() {
super();
this.state = {
name: "",
email: "",
password: "",
password2: "",
mobile: "",
errors: {},
open: false
};
this.menuRef = React.createRef();
}
...
- 接下来,添加
handleClick
和handleClose
方法:
handleClose = () => {
this.setState({
open: false
});
};
handleClick = () => {
this.setState({
open: true
});
};
还要确保将 state.open: false
添加到构造函数中。
- 最后,更改
Button
和Menu
标记以使用新定义的属性:
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={this.handleClick}
>
Open Menu
</Button>
<Menu
id="simple-menu"
ref={this.menuRef}
anchorEl={this.menuRef}
keepMounted
open={this.state.open}
onClose={this.handleClose}
>
<MenuItem onClick={this.handleClose}>Profile</MenuItem>
<MenuItem onClick={this.handleClose}>My account</MenuItem>
<MenuItem onClick={this.handleClose}>Logout</MenuItem>
</Menu>
Here's a demo的Menu
开闭,去掉了react-router
的功能