React - styling is kept after re-rendering

这一生的挚爱 提交于 2020-06-28 02:53:51

问题


I am learning react and built a simple program that generates array and changing it's color. I don't understand why when I generate new array the color of the previous one is kept. I thought that because the state has changed when I generated a new array react will re-render the component and the color will be set back to default. What am I missing?

Here is my code:

import React, { useState, useEffect } from 'react';

const Dummy2 = () => {
    const [arr, setArr] = useState([]);

    useEffect(() => {
        generateArray();
    }, []);

    const generateArray = () => {
        const temp = [];
        for(let i = 1; i < 11; i++) {
            temp.push(i * 2);
        }
        setArr(temp);
    }

    const changeColor = () => {
        const arrayElements = document.getElementsByClassName('array-element');
        for(let i = 0; i < arrayElements.length; i++) {
            arrayElements[i].style.backgroundColor = 'red';
        }
    }

    return (
        <div>
            <div className="array-container">
                {arr.map((value, idx) => (
                    <div className="array-element"
                         key={idx}
                         style={{height: `${value}px`,
                                 weight: `${value}px`,
                                 margin: '1px 1px',
                                 backgroundColor: 'blue'}}
                    ></div>))
                }
            </div>
            <div>
                <button onClick={() => changeColor()}>change-color!</button>
                <button onClick={() => generateArray()}>new-array</button>
            </div>
        </div>
    );
}

export default Dummy2;

EDIT: I manage to fix this by adding the following function

const resetColors = () => {
        const arrayBars = document.getElementsByClassName('array-element');
        for(let i = 0; i < arrayBars.length; i++) {
            arrayBars[i].style.backgroundColor = 'blue';
        }
    }

I called it whenever the array is reset.

But still I don't understand why the styling is kept.


回答1:


This is the wrong way to go about doing it - Generally, in react all values that can change should be handled as state. And all values that affect a components styling should be passed as props to a component - As a general rule of thumb, you should avoid things like getElementById and element.style =. Instead pass this information via props.

Firstly, you can handle the color with useState, and then setState of that color when a button is clicked. Then the color value can be passed into the style prop of the div that you want to style.

const Dummy2 = () => {
    const [arr, setArr] = useState([]);
    const [color, setColor] = useState("blue"); // Initialise color to "blue"

    /** -- snip -- **/

    const changeColor = () => {
        setColor("red"); // Set color here
    }

    return (
          /** -- snip -- **/
                    <div className="array-element"
                         key={idx}
                         style={{height: `${value}px`,
                                 weight: `${value}px`,
                                 margin: '1px 1px',
                                 backgroundColor: color, // pass in color here
                          }}
          /** -- snip -- **/
                <button onClick={() => changeColor()}>change-color!</button>
          /** -- snip -- **/
    );
}

If you wish to reset the color each time you generate an array, then you can call setColor("<whatever color you want>") inside of the generateArray() function. Then each time an array is generated, the color will be reset to that color.

As for why the styling is kept the same, it's because you are generating the same array each time. React is smart enough to know that it does not need to re-render a component/div that has the exact same values as the last render and so does not call a re-render.




回答2:


The React component is generally rerendered when it's state or props are changed.

So you should change your state to see the update.

import React, { useState, useEffect } from 'react';

const Dummy2 = () => {
    const [arr, setArr] = useState([]);
    const [color,setColor] = useState("blue");
    useEffect(() => {
        generateArray();
    }, []);

    const generateArray = () => {
        const temp = [];
        for(let i = 1; i < 11; i++) {
            temp.push(i * 2);
        }
        setArr(temp);
    };

    const changeColor = () => {   
         setColor("red");
    };

    return (
        <div>
            <div className="array-container">
                {arr.map((value, idx) => (
                    <div className="array-element"
                         key={idx}
                         style={{height: `${value}px`,
                                 weight: `${value}px`,
                                 margin: '1px 1px',
                                 backgroundColor: ${color}}}
                    ></div>))
                }
            </div>
            <div>
                <button onClick={() => changeColor()}>change-color!</button>
                <button onClick={() => generateArray()}>new-array</button>
            </div>
        </div>
    );
}

export default Dummy2;


来源:https://stackoverflow.com/questions/62396091/react-styling-is-kept-after-re-rendering

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!