Почему вызов дочернего компонента для обновления состояния в родительском компоненте выполняется медленнее, чем когда родительский компонент обновляет свое собственное состояние?

#reactjs

#reactjs

Вопрос:

CodePen: https://codepen.io/masm/pen/zYExBpr

У меня есть родительский компонент, App , который содержит список шестнадцатеричных цветов в состоянии. Я просматриваю его для отображения списка Input компонентов. Every Input просто отображает поле ввода, в котором значение, заданное для параметра color, передается вниз, а также обработчик onChange для обновления соответствующего состояния цвета App . Нажатие на New Color кнопку добавит новый цвет в список в состоянии in App .

Передается этот список цветов из App PreviewBox , который представляет собой поле, отображающее градиент из этого списка цветов.

Вот в чем проблема: когда я отображаю список Input компонентов, Input выполняется onChange поля ввода компонентов props.setColor() , но оно меняется очень медленно. Существует задержка, которая мешает мне свободно перетаскивать палитру цветов, и окно выбора цвета закрывается сразу после выбора цвета.

Однако, когда я просто отображаю список полей ввода в приложении, в отличие от рендеринга Input компонентов и передачи реквизитов, несмотря на наличие одинаковой информации, первое вообще не отстает, в то время как второе. Я бы действительно предпочел, чтобы каждое поле ввода было в своем собственном компоненте.

Кто-нибудь знает, почему это так?

Input.js

 import React, {useState} from 'react';

function Input(props) {

    return (
        <input type="color" value={props.color} onChange={(e) => props.changeColor(props.id, e.target.value)} />
    );
}

export default Input;
 

// App.js

 function App(props) {

  const [colors, setColors] = useState(["#FFFF00", "#000000"])

  const newColor = () => { 
    setColors(prev=>[...prev, "#ffffff"])
  }

  const changeColor = (id, color) => { 
    setColors(prevColors=>prevColors.map((current, index) => id===index ? color : current))
  }

  // THE PART IN QUESTION. Very slow when picking new color, lags
  // const inputArr = colors.map((color, index)=> <Input 
  //   key={index color} 
  //   color={color} 
  //   id={index} 
  //   changeColor={changeColor}
  // />)

  // color changes just fine with no lag, I'm able to drag 
  // colorpicker for each input very easily
  const inputs = colors.map((color, index) => <input 
    key={index} 
    type="color" 
    value={color} 
    onChange={(e) => changeColor(index, e.target.value)} 
  />)

  return (
    <>
      <PreviewBox colors={colors}/>
      {/* THE PART IN QUESTION */}
      {/* {inputArr} */} 
      {inputs}
      <button onClick={newColor}>New Color</button>
    </>      
  );
}
 

// PreviewBox.js (для контекста)

 function PreviewBox(props) {

    const [gradientStyle, setGradientStyle] = useState({
        background: `linear-gradient(0deg, ${props.colors[0]}, ${props.colors[1]})`,
        MozBackground: `linear-gradient(0deg, ${props.colors[0]}, ${props.colors[1]})`, 
        WebkitBackground: `linear-gradient(0deg, ${props.colors[0]}, ${props.colors[1]})`
    })

    useEffect(()=> { 
        
        setGradientStyle(prev=>{ 
            let newStr = props.colors.slice(1).reduce((final,acc)=>{
                return `${final}, ${acc}`
            }, `${props.colors[0]} `)
            return { 
                background: `linear-gradient(0deg, ${newStr})`,
                MozBackground: `linear-gradient(0deg, ${newStr})`,
                WebkitBackground: `linear-gradient(0deg, ${newStr})`
            }
        })
        
    }, [props.colors)
    
    return (
        <div style={{...gradientStyle,  width: "500px", height: "500px", border: "1px solid #000"}}>
        </div>
    );
}