我有一个内部带有表单的组件。表单的字段取决于在onChange方法中更新的组件的状态。单击提交按钮后,组件会将表单字段发送到父组件,然后更新商店。调用onChange方法时,错误“超出最大更新深度。当组件重复调用componentWillUpdate或componentDidUpdate内部的setState时,可能会发生此错误。React限制嵌套更新的数量以防止无限循环。”
我找不到“ MemberForm”组件内发生循环的原因。
但是,通过调试,我了解到在状态更改时(而不是onChange函数),还会呈现父组件“ AggiungiSocio”。但是,“ MemberForm”组件的状态与“ AggiungiSocio”组件无关。
是什么导致这种意外的渲染?如何避免呢?
奇怪的是,我还使用了“ ModificaSocio”组件中的“ MemberForm”组件,在其中我将表单字段作为属性传递。在此组件“ ModificaSocio”中,一切正常。
回顾
AddSocio -> MemberForm 不起作用
EditSocio -> MemberForm 有效
AggiungiSocio
import React, { Component, Fragment } from "react";
import {
Row,
Card,
CardBody,
CardTitle,
CardSubtitle,
} from "reactstrap";
import IntlMessages from "../../../helpers/IntlMessages";
import { Colxx } from "../../../components/common/CustomBootstrap";
import MemberForm from "../../../containers/form/MemberForm";
import {injectIntl} from "react-intl";
import {connect} from "react-redux";
import {addMemberDetail} from "../../../redux/memberDetail/actions";
import {Socio} from "../../../models/socio";
class AggiungiSocio extends Component {
constructor(props) {
super(props);
}
aggiungiSocio = (socio) => {
console.log(socio);
this.props.addMemberDetail(socio);
};
render() {
console.log("render aggiungi socio");
const {
loading
} = this.props.memberDetail;
return (
<Fragment>
<Row className="mb-4">
<Colxx xxs="12">
<Card>
<CardBody>
<CardTitle>
<IntlMessages id="pages.member.add-member"/>
</CardTitle>
<CardSubtitle>
<IntlMessages id="pages.member.add-member-description"/>
</CardSubtitle>
{loading ? (
<MemberForm onSubmit={this.aggiungiSocio}/>
) : (
<div className="loading"/>
)
}
</CardBody>
</Card>
</Colxx>
</Row>
</Fragment>
)
}
}
const mapStateToProps = ({memberDetail}) => {
return {
memberDetail
};
};
export default injectIntl(
connect(
mapStateToProps,
{
addMemberDetail
}
)(AggiungiSocio)
);
ModificaSocio
import React, { Component, Fragment } from "react";
import {
Row,
Card,
CardBody,
CardTitle
} from "reactstrap";
import IntlMessages from "../../../helpers/IntlMessages";
import { Colxx } from "../../../components/common/CustomBootstrap";
import "react-datepicker/dist/react-datepicker.css";
import MemberForm from "../../../containers/form/MemberForm";
import {injectIntl} from "react-intl";
import {connect} from "react-redux";
import {getMemberDetail, editMemberDetail} from "../../../redux/memberDetail/actions";
class ModificaSocio extends Component {
constructor(props) {
super(props);
this.state = {
};
}
modificaSocio = (socio) => {
this.props.editMemberDetail(socio);
}
render() {
const {
member,
loading
} = this.props.memberDetail;
return (
<Fragment>
<Row className="mb-4">
<Colxx xxs="12">
<Card>
<CardBody>
<CardTitle>
<IntlMessages id="pages.member.edit-member"/>
</CardTitle>
{loading ? (
<MemberForm member={member} onSubmit={this.modificaSocio}/>
): (
<div className="loading" />
)
}
</CardBody>
</Card>
</Colxx>
</Row>
</Fragment>
)
}
}
const mapStateToProps = ({memberDetail}) => {
return {
memberDetail
};
};
export default injectIntl(
connect(
mapStateToProps,
{
editMemberDetail,
getMemberDetail
}
)(ModificaSocio)
);
会员表格
import React, { Component } from "react";
import {
Input,
FormGroup,
Label,
Button,
Form
} from "reactstrap";
import IntlMessages from "../../helpers/IntlMessages";
import DatePicker from "react-datepicker";
import "react-tagsinput/react-tagsinput.css";
import "react-datepicker/dist/react-datepicker.css";
import "rc-switch/assets/index.css";
import "rc-slider/assets/index.css";
import "react-rater/lib/react-rater.css";
import { Colxx } from "../../components/common/CustomBootstrap";
import Select from "react-select";
import CustomSelectInput from "../../components/common/CustomSelectInput";
import moment from "moment";
import {Socio} from "../../models/socio";
class MemberForm extends Component {
constructor(props) {
super(props);
moment.locale("it");
this.state = {
member: (typeof this.props.member === 'undefined') ? Socio : this.props.member,
selectQualifica: [{
label: (typeof this.props.member === 'undefined') ? '' : this.props.member.qualifica,
value: (typeof this.props.member === 'undefined') ? '' : this.props.member.qualifica
}],
selectTitolo: [{
label: (typeof this.props.member === 'undefined') ? '' : this.props.member.titolo,
value: (typeof this.props.member === 'undefined') ? '' : this.props.member.titolo
}],
dataDiNascita: moment((typeof this.props.member === 'undefined') ? null : this.props.member.dataDiNascita, "DD/MM/YYYY"),
dataRichiestaIscrizione: moment((typeof this.props.member === 'undefined') ? null : this.props.member.dataRichiestaIscrizione, "DD/MM/YYYY"),
dataAccettazione: moment((typeof this.props.member === 'undefined') ? null : this.props.member.dataAccettazione, "DD/MM/YYYY")
}
}
handleChangeQualifica = qualifica => {
this.setState({
member: {
...this.state.member,
qualifica: qualifica.value
},
selectQualifica: [{
label: qualifica.value,
value: qualifica.value
}]
});
}
handleChangeTitolo = titolo => {
this.setState({
member: {
...this.state.member,
titolo: titolo.value
},
selectTitolo: [{
label: titolo.value,
value: titolo.value
}]
});
}
handlerChange = event => {
const name = event.target.name;
const value = event.target.value;
if (value!=this.state.member[name]) {
console.log("il valore è cambiato, aggiorno stato");
console.log(value, this.state.member[name]);
this.setState({
member: {
...this.state.member,
[name]: value
}
});
} else {
console.log("il valore è lo stesso!, non aggiorno stato");
console.log(value, this.state.member[name]);
}
}
handleChangeDataNascita = date => {
this.setState({
member: {
...this.state.member,
dataDiNascita: date.format("DD/MM/YYYY")
},
dataDiNascita: date
});
};
handleChangeDataRichiestaIscrizione = date => {
this.setState({
member: {
...this.state.member,
dataRichiestaIscrizione: date.format("DD/MM/YYYY")
},
dataRichiestaIscrizione: date
});
};
handleChangeDataAccettazione = date => {
this.setState({
member: {
...this.state.member,
dataAccettazione: date.format("DD/MM/YYYY")
},
dataAccettazione: date
});
};
handleSubmit = () => {
this.props.onSubmit(this.state.member);
}
render () {
console.log("render memberform");
const {
member,
selectQualifica,
selectTitolo,
dataDiNascita,
dataRichiestaIscrizione,
dataAccettazione
} = this.state;
return (
(member &&
<Form>
<FormGroup row>
<Colxx sm={2}>
<FormGroup>
<Label for="memberTitle">
<IntlMessages id="member.idSocio"/>
</Label>
<Input
disabled
readOnly
type="text"
name="memberId"
id="memberId"
defaultValue={member.numeroSocio}
/>
</FormGroup>
</Colxx>
<Colxx sm={2}>
<FormGroup>
<Label for="memberTitle">
<IntlMessages id="member.title"/>
</Label>
<Select
components={{Input: CustomSelectInput}}
className="react-select"
classNamePrefix="react-select"
name="form-field-name"
id="memberTitle"
options={[
{label: "Sig", value: "Sig", key: 0},
{label: "Sig.ra", value: "Sig.ra", key: 1}
]}
value={selectTitolo}
onChange={this.handleChangeTitolo.bind(this)}
/>
</FormGroup>
</Colxx>
<Colxx sm={3}>
<Label for="memberName">
<IntlMessages id="member.name"/>
</Label>
<Input
type="text"
name="nome"
id="memberName"
value={member.nome}
onChange={this.handlerChange.bind(this)}
/>
</Colxx>
<Colxx sm={3}>
<Label for="memberSurname">
<IntlMessages id="member.surname"/>
</Label>
<Input
type="text"
name="cognome"
id="memberSurname"
value={member.cognome}
onChange={this.handlerChange.bind(this)}
/>
</Colxx>
<Colxx sm={2}>
<Label for="memberSurname">
<IntlMessages id="member.birthday"/>
</Label>
<DatePicker
dateFormat="DD/MM/YYYY"
selected={dataDiNascita}
onChange={this.handleChangeDataNascita.bind(this)}
id="memberBirthday"/>
</Colxx>
</FormGroup>
<FormGroup row>
<Colxx sm={3}>
<FormGroup>
<Label for="birth-comune">
<IntlMessages id="member.birth-comune"/>
</Label>
<Input
type="text"
name="comuneDiNascita"
id="birth-comune"
onChange={this.handlerChange.bind(this)}
value={member.comuneDiNascita}
/>
</FormGroup>
</Colxx>
<Colxx sm={2}>
<FormGroup>
<Label for="birth-provincia">
<IntlMessages id="member.birth-provincia"/>
</Label>
<Input
type="text"
name="provinciaDiNascita"
id="birth-provincia"
onChange={this.handlerChange.bind(this)}
value={member.provinciaDiNascita}
/>
</FormGroup>
</Colxx>
<Colxx sm={4}>
<FormGroup>
<Label for="residential-address">
<IntlMessages id="member.residential-address"/>
</Label>
<Input
type="text"
name="indirizzoDiResidenza"
id="residential-address"
onChange={this.handlerChange.bind(this)}
value={member.indirizzoDiResidenza}
/>
</FormGroup>
</Colxx>
<Colxx sm={3}>
<FormGroup>
<Label for="codice-fiscale">
<IntlMessages id="member.codice-fiscale"/>
</Label>
<Input
type="text"
name="codiceFiscale"
id="codice-fiscale"
onChange={this.handlerChange.bind(this)}
value={member.codiceFiscale}
/>
</FormGroup>
</Colxx>
</FormGroup>
<FormGroup row>
<Colxx sm={3}>
<FormGroup>
<Label for="data-richiesta-iscrizione">
<IntlMessages id="member.data-richiesta-iscrizione"/>
</Label>
<DatePicker
dateFormat="DD/MM/YYYY"
selected={dataRichiestaIscrizione}
onChange={this.handleChangeDataRichiestaIscrizione.bind(this)}
id="data-richiesta-iscrizione"/>
</FormGroup>
</Colxx>
<Colxx sm={3}>
<FormGroup>
<Label for="data-accettazione">
<IntlMessages id="member.data-accettazione"/>
</Label>
<DatePicker
dateFormat="DD/MM/YYYY"
selected={dataAccettazione}
onChange={this.handleChangeDataAccettazione.bind(this)}
id="data-accettazione"/>
</FormGroup>
</Colxx>
<Colxx sm={3}>
<FormGroup>
<Label for="payment">
<IntlMessages id="member.payment"/>
</Label>
<Input
type="text"
name="quotaVersata"
id="payment"
onChange={this.handlerChange.bind(this)}
value={member.quotaVersata}
/>
</FormGroup>
</Colxx>
<Colxx sm={3}>
<FormGroup>
<Label for="qualification">
<IntlMessages id="member.qualification"/>
</Label>
<Select
components={{Input: CustomSelectInput}}
className="react-select"
classNamePrefix="react-select"
name="form-field-name"
id="qualification"
options={[
{label: "Socio", value: "Socio", key: 0},
{label: "Socio Fondatore", value: "Socio Fondatore", key: 1},
{label: "Consigliere", value: "Consigliere", key: 2}
]}
value={selectQualifica}
onChange={this.handleChangeQualifica}
/>
</FormGroup>
</Colxx>
</FormGroup>
<Button color="primary" onClick={this.handleSubmit.bind(this)}>
<IntlMessages id="pages.member.save"/>
</Button>
</Form>
)
)
}
}
export default React.memo(MemberForm);
答案 0 :(得分:0)
您不能将参数传递给函数之外的函数。
正确:
< ... onChange={function} />
不正确:
< ... onChange={function(params)} />
要使用参数,您需要将函数嵌套在匿名函数中:
< ... onChange={() => function(params)} />
如果您要编写此代码:
< ... onChange={() => this.handlerChange.bind(this)} />