简体   繁体   中英

Invariant Violation: Maximum update depth..when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate

I'm setting up user based authentication to only permit certain users to different components and different parts of our navbar.

This error only shows when I hit the "Create Templates" tab in the navbar twice. I'm not sure what's going on.

App.jsx

const TemplateAssignment = AuthorizedComponent(new Set(['admin', 'manage']));
const TemplateCreation = AuthorizedComponent(new Set(['admin']));
const TemplateModification = AuthorizedComponent(new Set(['admin', 'manage']));

export class App extends Component {
    componentDidMount() {
        this.props.getUser();
    }

    render() {
        console.log("THIS.PROPS.USEROLES IN APP: ", this.props)
        return this.props.authenticated ? (
            <Template title="Bulk Attribute Tool 2.0">
                <NavBar userRoles={this.props.userRoles} />
                {/* <ErrorBoundary> */}
                {/* <Router>
                    <Route path="/" component={TemplateAssignment(AgentTemplateAssignFlow)}>
                        <Route path="/create-new-template" component={TemplateCreation(CreateTemplateFlow)} />
                        <Route path="/modify-template" component={TemplateModification(ModifyTemplatePage)} />

                    </Route>
                </Router> */}
                {/* <Route exact path="/" component={TemplateAssignment(AgentTemplateAssignFlow)} />
                <Route path="/create-new-template" component={TemplateCreation(CreateTemplateFlow)} />
                <Route path="/modify-template" component={TemplateModification(ModifyTemplateFlow)} /> */}

                {/* </ErrorBoundary> */}

                {/* <div>
                    {this.props.retrieved &&
                        (this.props.authorized === true ? (
                            <div className="flex-container">
                                <NavBar userRoles={this.props.userRoles} />
                                <AgentTemplateAssignFlow />
                                <CreateTemplateFlow />
                            </div>
                        ) : (
                            <UserMessage className="alert" messageText={NOT_AUTHORIZED} messageType={SERVICE_ERR} />
                        ))}
                </div> */}

                <Route path="/" exact component={TemplateAssignment(Home)} />
                <Route path="/create-new-template" component={TemplateCreation(CreateNewTemplatePage)} />
                <Route path="/page2" component={TemplateModification(Page2)} />
            </Template>
        ) : (
            <Template title="TOOL">
                <UserMessage
                    className="alert"
                    messageText={this.props.statusMessage.messageText}
                    messageType={this.props.statusMessage.messageType}
                />
            </Template>
        );
    }
}

Navbar:

import React from 'react';
import './navbar.css';
import {Link} from 'react-router-dom';
import PropTypes from 'prop-types';

const userRole = userRoleProp => {
    let userAuthorized = false;
    if (userRoleProp.has('admin')) {
        userAuthorized = true;
    }
    return userAuthorized;
};

export const NavBar = props => {
    // console.log("PROPS IN NAVBAR: ", props)
    return (
        <nav className="navbar">
            <ul className="navBarList">
                <li className="navBarItem">
                    <Link to="/">Template Assignment</Link>
                </li>
                {userRole(props.userRoles) && (
                    <li className="navBarItem">
                        <Link to="/create-new-template">Create Templates</Link>
                    </li>
                )}
                {userRole(props.userRoles) && (
                    <li className="navBarItem">
                        <Link to="/page2">Modify Templates</Link>
                    </li>
                )}

            </ul>
        </nav>
    );
};

NavBar.propTypes = {
    userRoles: PropTypes.object
};

CreateNewTemplatePage:

export class CreateNewTemplatePage extends Component {
    constructor(props) {
        super(props);
        this.state = {
            modalIsActive: false,
            currentData: [],
            limit: 1
        };
        this.onSubmit = this.onSubmit.bind(this);
        this.onUpdate = this.onUpdate.bind(this);
        this.retryDepartment = this.retryDepartment.bind(this);
    }

    componentDidMount() {
        this.props.getCosaData();
        this.props.getSupplierData();
        this.props.getAllTemplateData();
    }

    componentWillUnmount() {
        this.props.clearMessage();
        this.hideModal();
    }

    showModal = modalIsActive => {
        this.setState({modalIsActive: true});
    };

    hideModal = modalIsActive => {
        this.setState({modalIsActive: false});
    };

    resetTemplate = () => {
        this.props.reset('templateForm');
        this.hideModal();
    };

    onSubmit() {
        this.props.history.push('/create-new-template-attributes');
    }

    onUpdate(event, value) {
        if (value) {
            this.setState({cosa: value});
            this.props.getDepartmentData(value);
        }
    }

    retryDepartment() {
        let value = this.state.cosa;
        if (value) {
            this.props.getDepartmentData(value);
            this.props.clearMessage();
        }
    }

    checkForRequestFailure() {
        let requestFailure = false;
        if (
            this.props.statusMessage.callsWithError.cosaRequestFailure ||
            this.props.statusMessage.callsWithError.supplierRequestFailure ||
            this.props.statusMessage.callsWithError.allTemplateRequestFailure
        ) {
            requestFailure = true;
        }

        return requestFailure;
    }

    render() {
        let {handleSubmit} = this.props;
        return (
            <div>
                {/* {this.props.userRoles.has('admin') ? ( */}
                    <div>
                        {this.checkForRequestFailure() ? (
                            <UserMessage
                                className="alert"
                                messageText={this.props.statusMessage.userMessage}
                                messageType={this.props.statusMessage.messageType}
                            />
                        ) : (
                            <div>
                                <header className="page-header">Create a New Template</header>
                                <UForm className="on-submit" onSubmit={handleSubmit(this.onSubmit)}>
                                    <FormSection label="Name/Description">
                                        <FormGroup>
                                            <Field
                                                className="usaa-input"
                                                component={Textarea}
                                                label="Template Name"
                                                name="name"
                                                maxLength={128}
                                                minRows={1}
                                                validate={[required, templateValidator]}
                                            />
                                            <Field
                                                component={Textarea}
                                                name="description"
                                                helpText="Please be descriptive."
                                                label="Template Description"
                                                maxLength={1024}
                                                minRows={1}
                                                validate={required}
                                            />
                                        </FormGroup>
                                    </FormSection>
                                    <FormSection label="COSA/Department">
                                        <FormGroup>
                                            {this.props.statusMessage.callsWithError.deptRequestFailure && (
                                                <UserMessage
                                                    className="alert"
                                                    messageText={this.props.statusMessage.userMessage}
                                                    messageType={this.props.statusMessage.messageType}
                                                />
                                            )}
                                            <Field
                                                className="cosa-input"
                                                component={Select}
                                                name="cosa"
                                                label="COSA"
                                                helpText="Please select a COSA"
                                                options={checkBoxFilter(this.props.cosaData)}
                                                validate={required}
                                                onChange={this.onUpdate}
                                            />
                                        </FormGroup>
                                        {this.props.statusMessage.callsWithError.deptRequestFailure && (
                                            <Button
                                                buttonname="try-again-button"
                                                label={
                                                    <p>
                                                        <span>Try Again </span>
                                                        <Icon name="cycle" size="lg" />
                                                    </p>
                                                }
                                                onClickMethod={this.retryDepartment}
                                            />
                                        )}
                                        <FormGroup>
                                            {this.props.departmentData.length > 0 && (
                                                <Field
                                                    component={CheckboxGroup}
                                                    name="department"
                                                    choices={checkBoxFilterDept(this.props.departmentData)}
                                                    label="Department"
                                                    maxCount={3}
                                                    validate={[required, departmentvalidator]}
                                                />
                                            )}
                                        </FormGroup>
                                    </FormSection>
                                    <FormSection label="Suppliers">
                                        <FormGroup>
                                            {this.props.supplierData.length > 0 && (
                                                <Field
                                                    component={CheckboxGroup}
                                                    name="suppliers"
                                                    choices={checkBoxFilter(this.props.supplierData)}
                                                    label="Suppliers"
                                                    helpText="Please select Suppliers"
                                                    validate={required}
                                                />
                                            )}
                                        </FormGroup>
                                    </FormSection>
                                    <ButtonContainer
                                        primaryAction={<SubmitButton allProps={this.props} proceedLabel="Next" />}
                                        secondaryActions={
                                            <Button
                                                type="button"
                                                buttonname="clear-all-button-form"
                                                label="Clear All"
                                                onClickMethod={this.showModal}
                                                disabled={!this.props.templateFormData}
                                            />
                                        }
                                    />
                                    <Modal
                                        active={this.state.modalIsActive}
                                        headerTitle="Are you sure you wish to remove all attributes?"
                                        onClose={this.hideModal}
                                        className="clear-all-modal"
                                    >
                                        <div className="clear-all-modal-content">
                                            <Button
                                                type="clearAll"
                                                buttonname="clear-template-form"
                                                label="Yes"
                                                onClickMethod={this.resetTemplate}
                                            />
                                            <Button
                                                type="cancel"
                                                buttonname="cancel-clear-form"
                                                label="No"
                                                onClickMethod={this.hideModal}
                                            />
                                        </div>
                                    </Modal>
                                </UForm>
                            </div>
                        )}
                    </div>

            </div>
        );
    }
}

Expected to not show error whenever the different tabs in the navbar are shown.

Not sure if this is the exact cause of the error, but you are calling this.hideModal() , which sets state, inside of componentWillUnmount() . You don't need to reset state here, since the component will be unmounted and the state will reset anyways.

Removing that unnecessary function that calls setState might resolve your issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM