Как вы условно отображаете динамически созданные дочерние компоненты в React? В частности: компоненты, созданные с помощью сопоставления через JSON

#reactjs

#reactjs

Вопрос:

Я визуализирую некоторые компоненты с помощью сопоставления через JSON, каждый из которых содержит div, который дополнительно содержит два divs и их соответствующие дочерние компоненты. Я бы хотел, чтобы кнопка в «дочернем компоненте a» запускала отображение / скрытие css-класса для «дочернего компонента b», но конкретно экземпляра, связанного с тем, где он был запущен, сохраняя при этом логику в родительском. Моя первая мысль — использовать идентификатор для условной установки классов, но мне трудно концептуализировать логику. В настоящее время я просто использую перехваты и не очень знаком с Redux, но что-то подсказывает мне, что это может потребоваться здесь. Есть идеи или рекомендации?

Еще немного информации для контекста: это приложение с цветовой палитрой, которое извлекает данные из API и отображает 5 цветов. Каждый цвет (дочерний компонент a) имеет кнопку для открытия соответствующего редактора (дочерний компонент b). Первоначально у меня был редактор в цветовом компоненте, который полностью устраняет эту проблему, но затем у меня возникла проблема с невозможностью контролировать их столкновения (несколько редакторов открываются одновременно). Я, конечно, мог бы жестко запрограммировать все пять (10) компонентов по отдельности, но я знаю, что это неправильное решение и предотвратило бы некоторые будущие функции (например, динамическое управление количеством цветов).

Еще одна проблема, с которой я сталкиваюсь, заключается в том, что передача значения useState в качестве реквизита не преобразуется (editorVisible) в дочернем элементе. например, console.log(editorVisible) в родительском возвращает логическое значение, но в дочернем возвращает неопределенное. Здесь также может пригодиться некоторое представление.

Родительский код: этот код, как и ожидалось, устанавливает класс для всех пяти редакторов. Мне нужно решение для их индивидуального таргетинга при сохранении рендеринга через map:

 const ComposerPane = () => {
  const colors = data
  const [editorVisible, setEditorVisible] = useState()
  const [editorInitialClass, setEditorInitialclass] = useState('editor-container-initial')

  const toggle = () => {
    console.log(editorVisible)
    setEditorVisible(!editorVisible)
    setEditorInitialclass('editor-animate-return')
  }
  
  const editColor = (e) => {
    console.log(e.target.value)
  }

  return (
    <div className='composer-container'>
      {colors.map((color) => (
        <div key={color.id} className='composer-fix'>
          <div className="color-comp-container">
            <ColorComp
              id={color.id}
              red={color.red}
              green={color.green}
              blue={color.blue}
              hex={color.hex}
              toggle={toggle}
            />
          </div>
          <div className={
            editorVisible ?
              'editor-container editor-animate' :
              `${editorInitialClass} editor-container`
          }>
            <Editor
              id={color.id}
              red={color.red}
              green={color.green}
              blue={color.blue}
              hex={color.hex}
              editColor={editColor}
              editorVisible={editorVisible}
              editorInitialClass={editorInitialClass}
            />
          </div>
        </div>
      ))}
    </div>
  )
}

 

И отдельный дочерний компонент color:

 const ColorComp = ({ id, red, green, blue, hex, toggle, editorVisible, editorInitialClass }) => {

  // Sets new color to color object
  const BGcolorValue = Color.rgb(parseInt(red), parseInt(green), parseInt(blue))

  // Background-color css
  const BGColor = { backgroundColor: `rgb(${red}, ${green}, ${blue})` }

  // Sets text and icon color value based on background
  const foreColor = BGcolorValue.isLight() ? 'rgba(0,0,0,.5)' : 'rgba(255,255,255,.5)'

  // CSS values
  const hexStyle = { color: foreColor }
  const indicatorStyle = { backgroundColor: foreColor }
  const iconFillStyle = { fill: foreColor }

  return (
    <div className='color-comp' style={BGColor}>
      <div className={editorVisible ?
        'editorIndicatorContainer editor-animate' :
        `${editorInitialClass} editorIndicatorContainer`
      }>
        <p className='hexIndicator' style={hexStyle}>#{hex.toUpperCase()}</p>
        <div className='editorIndicator' style={indicatorStyle} />
      </div>
      <CustomButton
        onClick={() => {
        toggle();
        console.log(editorVisible);
        }}
        foreColor={foreColor}
        className='editorIcon'
        style={iconFillStyle}><EditorIcon /></CustomButton>
    </div>
  )
}
 

Компонент редактора:

 const Editor = ({ id, red, green, blue, editColor }) => {
  return (
  <div className='editor' id={id}>
    <div className='EditorPane'>
      <button className='EditorButton Done'>DONE</button>
      <div className='Slider'>
        <p className='SliderLabel'>R:</p>
        <input className='SliderInput' type='text' value={red} onChange={editColor}></input>
        <input className='EditorSlider' name='red' type='range' min='0' max='255' value={red} onChange={editColor}/>
      </div>
      <div className='Slider'>
        <p className='SliderLabel'>G:</p>
        <input className='SliderInput' type='text' value={green} onChange={editColor}></input>
        <input className='EditorSlider' name='green' type='range' min='0' max='255' value={green} onChange={editColor}/>
      </div>
      <div className='Slider'>
        <p className='SliderLabel'>B:</p>
        <input className='SliderInput' type='text' value={blue} onChange={editColor}/>
        <input className='EditorSlider' name='blue' type='range' min='0' max='255' value={blue} onChange={editColor}/>
      </div>
    </div>
  </div>
  )
}
 

Комментарии:

1. Чтобы указать вам правильное направление, вы можете разблокировать много энергии, сохранив активный идентификатор цвета в состоянии вместо editorVisible логического значения. Если редактор должен быть закрыт, установите activeColorId состояние на null . Этот единственный элемент состояния теперь сообщает вам, отображать редактор или нет, а также о том, какой цвет его вызвал. Вы можете передавать этот идентификатор и делать некоторые интересные вещи, например, выделять активный образец цвета. Для этого вам не нужен Redux 🙂

2. Спасибо, это имеет смысл, даст этому ход.