我具有以下组件层次结构:
- Page
-- Table
-- ModalForm
-- Fab
通过单击Fab(左下角的圆形按钮),我打开空白的modalForm(material-ui对话框组件)以创建新条目。 我也想对Table中的编辑条目使用相同的表单。但是Form是受状态控制的,而且打开时我无法从道具读取数据到状态(此事件不是ComponentDidMounted或其他类型的生命周期,只是更改了Dialog组件的道具“打开” )。
这部分代码不起作用:
componentWillReceiveProps() {
const { fullname, birthday, gender } = this.props.data;
console.log("this.props.data", this.props.data);
this.setState({ fullname, birthday, gender });
console.log("componentWillReceiveProps this.state ", this.state);
}
这是Page(父组件)的外观:
import React, { Component } from "react";
import { Fab, CircularProgress } from "@material-ui/core";
import AddIcon from "@material-ui/icons/Add";
import Table from "./Table";
import Form from "./Form";
import { connect } from "react-redux";
import { firestoreConnect, isLoaded } from "react-redux-firebase";
import { compose } from "redux";
export class Page extends Component {
state = { isModalOpen: false, data: {} };
openModal = data => event => {
const defaultData = data || { fullname: "Aaa", birthday: "1984-11-11", gender: "Жен" };
this.setState({ data: defaultData });
this.setState({ isModalOpen: true });
console.log("defaultData", defaultData);
};
closeModal = () => {
this.setState({ isModalOpen: false });
};
render() {
const { athlets } = this.props;
/* if (athlets) {
console.log("athlets.length", athlets.length);
} */
return (
<main>
{isLoaded(athlets) ? (
<Table
athlets={athlets}
toggleModal={this.toggleModal}
firestoreDelete={this.props.firestore.delete}
/>
) : (
<CircularProgress />
)}
<Fab style={fabStyle} onClick={this.openModal(null)} color="primary" aria-label="Add">
<AddIcon />
</Fab>
<Form
isModalOpen={this.state.isModalOpen}
data={this.state.data}
closeModal={this.closeModal}
firestoreAdd={this.props.firestore.add}
/>
</main>
);
}
}
const mapStateToProps = state => {
return {
athlets: state.firestore.ordered.athlets
};
};
export default compose(
connect(mapStateToProps),
firestoreConnect([{ collection: "athlets" }])
)(Page);
const fabStyle = {
margin: 0,
top: "auto",
right: 20,
bottom: 20,
left: "auto",
position: "fixed"
};
子组件表单的外观如下:
import React from "react";
import {
Button,
TextField,
Typography,
FormHelperText,
FormControl,
InputLabel,
Select,
Dialog,
DialogActions,
DialogContent,
DialogTitle
} from "@material-ui/core";
// import { Link, Redirect } from "react-router-dom";
import styles from "./styles";
import { connect } from "react-redux";
// import { signIn } from '../../store/actions/authActions';
const initialState = { fullname: "", birthday: "", gender: "" };
class Form extends React.Component {
state = initialState;
//state = { ...this.props.data };
componentWillReceiveProps() {
const { fullname, birthday, gender } = this.props.data;
console.log("this.props.data", this.props.data);
this.setState({ fullname, birthday, gender });
console.log("componentWillReceiveProps this.state ", this.state);
}
handleChange = e => {
// console.log("e.target.id & value", e.target, e.target.value);
// const id = e.target.id || "gender";
this.setState({
[e.target.id]: e.target.value
});
};
handleSubmit = () => {
const { fullname, birthday, gender } = this.state;
console.log("this.state", this.state);
const createdBy = { userName: this.props.profile.username, userId: this.props.auth.uid };
const firestoreAdd = this.props.firestoreAdd(
{ collection: "athlets" },
{ fullname, birthday, gender, createdBy }
);
firestoreAdd.catch(error => {
console.log("firestoreAdd error", error);
});
this.handleCancel();
};
handleDelete = () => {
const { id, name, image } = this.state;
const confirmation = window.confirm("Are you sure? ");
if (confirmation) this.props.deleteAuthor({ id, name, image }, "authors");
this.props.toggleModal();
};
handleCancel = () => {
this.props.closeModal();
};
render() {
const { authError } = this.props;
//const { fullname, birthday, gender } = this.state;
const { id, fullname, birthday, gender } = this.state;
//if (auth.uid) return <Redirect to="/" />;
return (
<div style={styles.flexContainer}>
<Dialog
open={this.props.isModalOpen}
onClose={this.handleClose}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">
<Typography color="primary">Добавление спортсмена</Typography>
</DialogTitle>
<DialogContent>
{/* FULLNAME */}
<TextField
onChange={this.handleChange}
id="fullname"
label="ФИО"
type="text"
value={fullname}
margin="normal"
autoFocus
fullWidth
InputLabelProps={{
shrink: true
}}
/>
<br />
{/* BIRTHDAY */}
<TextField
onChange={this.handleChange}
id="birthday"
label="Дата рождения"
type="date"
value={birthday}
margin="normal"
fullWidth
InputLabelProps={{
shrink: true
}}
/>
{/* GENDER */}
<FormControl fullWidth /* className={classes.formControl} */>
<InputLabel htmlFor="gender">Пол</InputLabel>
<Select
native
value={gender}
onChange={this.handleChange}
inputProps={{
name: "gender",
id: "gender"
}}
>
<option value="" />
<option value="Муж">Муж</option>
<option value="Жен">Жен</option>
</Select>
</FormControl>
<br />
<FormHelperText error>{authError ? authError : null}</FormHelperText>
{/* <FormHelperText>
Don't have an accout? Please <Link to="/register">register</Link>.
</FormHelperText> */}
</DialogContent>
<DialogActions>
<Button /* onClick={this.handleDelete} */ color="secondary">Delete</Button>
<Button onClick={this.handleCancel} color="primary">
Cancel
</Button>
<Button onClick={this.handleSubmit} color="primary">
Save
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
const mapStateToProps = state => {
return {
// authError: state.auth.authError,
auth: state.firebase.auth,
profile: state.firebase.profile
};
};
const mapDispatchToProps = dispatch => {
return {
// signIn: creds => dispatch(signIn(creds))
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(Form);
请分享您的想法。