简体   繁体   中英

Child component, infinitely re-rendering

I am having trouble understanding why my component is being infinitely re-rendered

Parent Render: this part is incredibly large so I'm only including the section that uses the child component

 <Container
              style={{ alignItems: "center", height: 350, width: 1000 }}
            >
                <RenderQuestion 
                    questionVersion={this.state.questionVersion}
                    base1={this.state.base1}
                    base2={this.state.base2}
                    exp1={this.state.exp1}
                    exp2={this.state.exp2}
                    ansbase={this.state.ansbase}
                    ansexp={this.state.ansexp}
                    multiple={this.state.multiple}
                    // EDIT: it might be a bit confusing but multiple here 
                    is just a randomly generated number
                />
   ...
</Container>

Child Component - RenderQuestion //this works normally

const RenderQuestion = (props) => {
    switch (props.questionVersion) {
    ...
    case 11:
            return(
                <Row style={{ paddingTop: "50px", fontFamily: "courier", fontWeight: "bold", fontSize: 70, }}>
                    {/* Left Side */}
                    <Col style={{
                        textAlign:"right"
                    }}>
                        <Undeterminable
                            operator={props.multiple}
                            base1={props.base1}
                            base2={props.base2}
                            exp1={props.exp1}
                            exp2={props.exp2}
                        />
                    </Col>

                    {/* Equal Sign */}
                    <Col xs="1">=</Col>
                    {/* Right Side */}
                    <Col xs="4" style={{
                        textAlign:"left"
                    }}>
                        <span>
                            {props.ansbase}<sup>{props.ansexp}</sup>
                        </span>
                    </Col>
                </Row>
            );
     ...

Child's Child Component - Undeterminable //This is the part that is getting infinitely re-rendered

const Undeterminable = (props) => {
    let operator = "";
    let result = "";
    // random 1-4
    let random = Math.floor(Math.random()*4)+1;
    switch(props.operator) {
        case 1:
            operator = "+"
            break;
        case 2:
            operator = "-"
            break;
        case 3:
            operator = "x"
            break;
        case 4:
            operator = "÷"
            break;
    };

    switch(random){
        case 1:
            result = <span>
                ?<sup>{props.exp1}</sup>
                {" "} {operator} {" "}
                {props.base2}<sup>{props.exp2}</sup>
            </span>
            break;
        case 2:
            result = <span>
                {props.base1}<sup>?</sup>
                {" "} {operator} {" "}
                {props.base2}<sup>{props.exp2}</sup>
            </span>
            break;
        case 3:
            result = <span>
                {props.base1}<sup>{props.exp1}</sup>
                {" "} {operator} {" "}
                ?<sup>{props.exp2}</sup>
            </span>
            break;
        case 4:
            result = <span>
                {props.base1}<sup>{props.exp1}</sup>
                {" "} {operator} {" "}
                {props.base2}<sup>?</sup>
            </span>
            break;
    }
    return result;
}

To TL:DR depict what this code is supposed to do is it renders a basic equation with exponents x^a (+/-/*/÷) y^b where any of the numbers (x/a/y/b) are randomly loaded as a "?" instead of its value

However the component is being infinitely re-rendered so when displayed, it is constantly randomly changing which item is the "?", causing the equation to infinitely flicker and change. The wierdest thing about this is that the operator never changes during the infinite render.

EDIT: In Case 10 of my RenderQuestion I use a different child component Multiple which is this:

const Multiple = (props) => {
    let result = [];
    for(let i = 0; i < props.multiple -1; i++){
        result.push(<>{props.base1}<sup>{props.exp1}</sup> + </>)
    }
    
    return <span>{result}</span>;
};

which also infinitely renders (if i add console.log statements anywhere here, it will infinitely log), but since this doesn't change the displayed data or interfere with the rest of the app, I didnt mention it in the OP, but it seems more information might lead to a better understanding

Every time your component is rendered, random is recalculated inside of Undeterminable . Notice that operator value is stored inside of props , and that has the correct behavior.

There are a couple of approaches you can take to fix your problem:

  1. You can put random into your props to store the value.
  2. Alternatively, you could store the value of random in the state, using something like the useState hook.

For useState , make sure you import it and then try something like:

import React, { useState } from 'react';

const Undeterminable = (props) => {
  // random 1-4
  const [random] = useState(Math.floor(Math.random() * 4) + 1);
  ...
}

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