React-重新渲染后保留样式

时间:2020-06-15 20:03:17

标签: reactjs react-hooks styling

我正在学习反应,并构建了一个简单的程序来生成数组并更改其颜色。我不明白为什么在生成新数组时会保留前一个的颜色。我以为,因为在生成新数组时状态已更改,所以react将重新渲染组件并将颜色设置回默认值。我想念什么?

这是我的代码:

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;

编辑:我设法通过添加以下功能来解决此问题

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

每当重置数组时,我都会调用它。

但是我仍然不明白为什么要保留样式。

2 个答案:

答案 0 :(得分:1)

这是错误的方法-通常,在反应中,所有可以更改的值都应作为状态来处理。并且所有影响组件样式的值都应作为道具传递给组件-作为一般经验法则,应避免使用getElementByIdelement.style =之类的东西。而是通过道具传递此信息。

首先,您可以使用useState处理颜色,然后单击按钮时使用setState处理该颜色。然后,可以将颜色值传递到要设置样式的div的样式道具中。

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 -- **/
    );
}

如果您希望在每次生成数组时重置颜色,则可以在setColor("<whatever color you want>")函数内部调用generateArray()。然后,每次生成数组时,颜色都会重置为该颜色。

为什么要保持样式相同,这是因为每次都生成相同的数组。 React足够聪明,知道它不需要重新渲染与上次渲染具有完全相同值的component / div,因此不调用重新渲染。

答案 1 :(得分:0)

当状态或道具更改时,通常会重新渲染React组件。

因此,您应该更改状态以查看更新。

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;