componentDidMount продолжает звонить несколько раз после смены реквизита - PullRequest
0 голосов
/ 25 мая 2018

У меня проблема с бесконечным циклом componentDidMount , вызывающим себя бесконечно, когда я делаю что-то вроде этого:

this.props.setRootState({industries: ['hello','world']});

Весь код выглядит так:

import React from 'react';
import {Route, Link} from 'react-router-dom';
import FourthView from '../fourthview/fourthview.component';
import {Bootstrap, Grid, Row, Col, Button, Image, Modal, Popover} from 'react-bootstrap';
import Header from '../header/header.component';
import style from './information.style.scss';
import industryApi from '../industries/industry.api';

class InformationFilter extends React.Component {

    constructor(props) {
        super(props);
        this.state = {};
    }

    componentDidMount() {
        industryApi.getAll().then(response => {
            if (response.data) {
                this.props.setRootState({industries: response.data._embedded.industries});
            } else {
                console.log(response);
            }
        });
    }


    onIndustryChangeOption(event) {
        this.props.setRootState({selectedIndustry: event.target.value});
    }

    onJobChangeOption(event) {
        this.props.setRootState({selectedJob: event.target.value});
    }

    render() {
        return (
            <div className={"wrapperDiv"}>
                <div className={"flexDivCol"}>
                    <div id="header">
                        <Header size="small"/>
                    </div>
                    <div id="industryFilter">
                        <h2 className={"center"} style={{marginBottom: '25px'}}>Tietoa Aloista</h2>
                        <p className={"primaryColor center"}>Valitse opintoala</p>
                        <div className={"industries dropdownListHolder center"}>
                            <select id={"dropdownList"} onChange={(e) => this.onIndustryChangeOption(e)}
                                    value={this.props.rootState.selectedIndustry}>
                                {this.props.rootState.industries.map((industry, i) => <option key={i}
                                                                                              value={industry.id}>{industry.title}</option>)}
                            </select>
                        </div>
                        <p className={"primaryColor center"}>Valitse työtehtävä</p>
                        <div className={"jobs dropdownListHolder center"}>
                            <select id={"dropdownList"} onChange={(e) => this.onJobChangeOption(e)}
                                    value={this.props.rootState.selectedJob}>
                                {this.props.rootState.industries.map((job, i) => <option key={i}
                                                                                         value={job.id}>{job.text}</option>)}
                            </select>
                        </div>
                    </div>

                    <div id="industryDescription">
                        <h4>Ravintola- ja cateringala</h4>
                        <p className={"secondaryColor"}>
                            Donec facilisis tortor ut augue lacinia, at viverra est semper.
                            Sed sapien metus, scelerisque nec pharetra id, tempor a tortor. Pellentesque non dignissim
                            neque. Ut porta viverra est, ut dignissim elit elementum ut. Nunc vel rhoncus nibh, ut
                            tincidunt turpis. Integer ac enim pellentesque, adipiscing metus id, pharetra odio. 
                        </p>
                        <p className={"secondaryColor"}>
                            Donec facilisis tortor ut augue lacinia, at viverra est semper.
                        Sed sapien metus, scelerisque nec pharetra id, tempor a tortor. Pellentesque non dignissim
                        neque. Ut porta viverra est, ut dignissim elit elementum ut. Nunc vel rhoncus nibh, ut
                        tincidunt turpis. Integer ac enim pellentesque, adipiscing metus id, pharetra odio. 
                        </p>
                    </div>

                    <div id={"btnFilter"}>
                        <Link to='/information-job'>
                            <div onClick={() => this.props.setRootState({globalVariable: 'bar'})}>
                                <Button className={"primaryBtn"}>Seuraava</Button>
                            </div>
                        </Link>
                    </div>
                </div>
            </div>
        );
    }
}
export default InformationFilter;

Routes.js

import React from "react";
import {HashRouter, Route, Switch, Redirect, Link} from 'react-router-dom';
import Main from './components/main/main.component';
import SecondView from './components/secondview/secondview.component';
import ThirdView from './components/thirdview/thirdview.component';
import Traineeship from './components/traineeship/traineeships.component';
import InformationFilter from "./components/information/information-filter.component";
import InformationJob from "./components/information/information-job.component";

class AppRoutes extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            selectedIndustry: '',
            selectedJob: '',
            industries: [],
            jobs: [],
        }
    }

    render() {
        const InformationFilterPage = () => <InformationFilter rootState={this.state}
                                                               setRootState={this.setState.bind(this)}/>;

        const InformationJobPage = () => <InformationJob rootState={this.state}
                                                         setRootState={this.setState.bind(this)}/>;

        const TraineeshipPage = () => <Traineeship rootState={this.state}
                                                   setRootState={this.setState.bind(this)}/>;
        return (
            <HashRouter>
                <Switch>
                    <Route exact path='/' component={Main}/>
                    <Route path='/secondview' component={SecondView}/>
                    <Route path='/traineeships' component={TraineeshipPage}/>
                    <Route path='/information-filter' component={InformationFilterPage}/>
                    <Route path='/information-job' component={InformationJobPage}/>
                    <Redirect from='*' to='/'/>
                </Switch>
            </HashRouter>
        );
    }
}

export default AppRoutes;

Кто-нибудь знает, что здесь происходит?Я сохраняю состояние в этом компоненте из-за пересекающихся значений, вы можете сказать, почему вы не используете redux, но дело в том, что я не хочу использовать для этого проекта, так как это довольно маленький проект!

1 Ответ

0 голосов
/ 25 мая 2018

Когда вы вызываете setState для родительского компонента с помощью setRootState, он устанавливает состояние родительского элемента, который вызывает повторное рендеринг своих дочерних элементов, что вызывает повторное монтирование дочерних элементов, которое вызывает componentDidMount, которое затем снова устанавливает состояние родительского элемента ицикл продолжается.

Для решения этой проблемы вы должны вызвать ваш API и установить состояние в самом родительском компоненте.

ваш родительский компонент должен теперь иметь

componentDidMount() {
  this.industryApiCall ()
}

industryApiCall = () => {
  industryApi.getAll().then(response => {
    if (response.data) {
      this.props.setState({
        industries: response.data._embedded.industries
      })
    } else {
      console.log(response)
    }
  })
}

иВы можете передать эту функцию своим детям, например,

const InformationFilterPage = () => <InformationFilter rootState={this.state}
                               callApi={this.industryApiCall.bind(this)} />;

и использовать ее внутри компонента вашего ребенка, вызвав

this.props.callApi ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...