React - глючные проблемы с моим простым компонентом переключателя, размещенным в сетке css

Я создаю свое первое приложение для реагирования, и важным компонентом для моего приложения является эстетический набор переключателей, которые будут использоваться на большинстве страниц моих приложений, значения которых используются для фильтрации моих данных, которые отображаются на графике. Чтобы сделать этот компонент проще, я решил использовать компоненты ToggleButton и ToggleButtonGroup из react-bootstrap, а затем создать свой презентационный компонент ToolButtonGroup как своего рода оболочку вокруг компонентов react-bootstrap.

Что у меня есть для ToolButtonGroup.js:

import React, {Component} from 'react';
import { ToggleButton, ToggleButtonGroup } from 'react-bootstrap';

class ToolButtonGroup extends Component {

    constructor(props) {
        super(props);
    }

    handleChartTypeChange = (e) => {
        this.props.handler();
    }

    render() {

        // Get Variables from the params prop
        const { header, buttons, initialVal } = this.props.params;
        const { borderRadius, margin, padding, fontsize, border } = this.props.params;
        const { gridID, gridColumns, minRowHeight } = this.props.params;

        // Create the individual buttons
        const pageButtons = buttons.map((buttoninfo, idx) => {
            return (
                <ToggleButton 
                    key={idx}
                    style={{
                        "borderRadius": borderRadius, 
                        "margin": margin,
                        "padding": padding,
                        "fontSize": fontsize,
                        "border": border
                    }}
                    bsSize="large"
                    value={buttoninfo.value}>
                {buttoninfo.label}
                </ToggleButton>
            )
        })

        // Return the button group
        return(
            <div className="buttons-container"
                 style={{"border": "1px solid red";}}
                 id={gridID}>
                <h2 style={{
                  "width": "100%";
                  "margin": "0 auto";
                  "fontSize": "1.75em";
                  "marginTop": "5px";   
                  "border": "none";
                }}
                >{header}</h2>
                <ToggleButtonGroup 
                    type="radio"
                    name="charttype-options" 
                    defaultValue={initialVal} 
                    onChange={this.props.handler}
                    style={{
                        "display": "grid",
                        "gridTemplateColumns": "repeat(" + gridColumns + ", 1fr)",
                        "gridAutoRows": "auto",
                        "gridGap": "8px"
                    }}
                >
                    {pageButtons}
                </ToggleButtonGroup>
            </div>
        )
    }   
}

export default ToolButtonGroup;

Я использовал параметры, переданные этому компоненту, чтобы создать CSS-сетку ToggleButtons в ToggleButtonGroup. Данные/начальное значение для кнопок, большая часть стилей, а также данные сетки поступают в качестве реквизита из родительского компонента.

(На самом деле я не уверен, что использование компонентов react-bootstrap упростило или усложнило для меня этот компонент...)

Наконец, для демонстрации вызова ToolButtonGroup у меня есть компонент-контейнер starterContainer.js, который создает две группы кнопок инструментов:

import React, {Component} from 'react';
import ToolButtonGroup from 'ToolButtonGroup';

// Import CSS for this App
import './starterContainer.css';

class StarterApp extends Component {
    constructor(props){
        super(props);
        this.state = {
            pitchersOrHitters: "",
            position: ""
        }
    }

    // Button and Select Handlers!
    handlePitchHitChange = (pitchersOrHitters) => {
        this.setState({pitchersOrHitters})
    }
    handlePositionChange = (position) => {
        this.setState({ position: position });
    }

    render() {

        // 0. Load State and Props 
        const { pitchersOrHitters, position } = this.state;


        // Pitcher or Hitter Radio Button Group params
        const pitchOrHitButtonGroup = {
            borderRadius: "25px",
            margin: "1% 10%",
            padding: "5%",
            fontsize: "2em",
            border: "2px solid #BBB",

            gridColumns: 1, minRowHeight: "10px", "gridID": "buttons1",

            header: "Choose One:",          
            buttons: [
                { value: "Pitchers", label: "Pitchers" },
                { value: "Hitters", label: "Hitters" },
            ],
            initialVal: "Pitchers"}

        // Pitcher or Hitter Radio Button Group params
        const positionButtonGroup = {
            borderRadius: "10px",
            margin: "1% 10%",
            padding: "5%",
            fontsize: "1.25em",
            border: "2px solid #BBB",

            gridColumns: 4, minRowHeight: "20px", "gridID": "buttons2",

            header: "Choose One:",          
            buttons: [
                { value: "SP", label: "SP" },
                { value: "RP", label: "RP" },
                { value: "1B", label: "1B" },
                { value: "2B", label: "2B" },
                { value: "SS", label: "SS" },
                { value: "3B", label: "3B" },
                { value: "LF", label: "LF" },
                { value: "RF", label: "RF" },
                { value: "CF", label: "CF" }
            ],
            initialVal: "SP"}


        return(
            <div className="chart-grid-container">
                <ToolButtonGroup
                    params={pitchOrHitButtonGroup}
                    value={pitchersOrHitters}
                    handler={this.handlePitchHitChange} />    

                <ToolButtonGroup
                    params={positionButtonGroup}
                    value={position}
                    handler={this.handlePositionChange} />    
            </div>
        )
    }
}

Единственное дополнение — это css-сетка для макета группы кнопок и других компонентов. Эта сетка для staterContainer также будет иметь много других компонентов, включая виджеты Select и другие компоненты виджетов, а также компоненты, которые сами строят графики D3. Сначала эта css-сетка starterComponent кажется бесполезной, но позже она будет полезна для моих страниц, и я хотел бы сохранить ее.

starterComponent.css

.chart-grid-container {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    grid-auto-rows: minmax(200px, auto);
    grid-gap: 5px;
    grid-template-areas:
        "btns1 btns1 btns2 btns2 btns2 btns2 . . . . . .";
}

#buttons1 { grid-area: btns1; }     
#buttons2 { grid-area: btns2; }     

В связи с этим у меня есть несколько вопросов/проблем:

введите здесь описание изображения введите здесь описание изображения

<сильный>1. Ошибка: когда мой компонент изначально загружается, ToggleButtons висят за границей, обозначенной в родительском контейнере для сетки CSS. Однако, когда я нажимаю любую из кнопок, ToggleButtons изменяет размер, чтобы поместиться внутри контейнера сетки. Я полагаю, что это происходит из-за некоторого недопонимания форматирования между двумя компонентами, но я не знаю, как это исправить.

  1. Моя функция handleChartTypeChange ничего не делает, так как я передаю this.props.handler непосредственно в ToggleButtonGroup. Могу ли я избавиться от handlechartTypeChange? Или я должен использовать его все еще?

  2. Мой starterContainer имеет 2 функции смены дескриптора... есть ли простой способ превратить это в 1 функцию смены дескриптора? Это кажется дублирующим, и у меня может быть более 2 групп кнопок на странице.

  3. В общем, как компонент, который будет использоваться в большинстве моих приложений и иметь важную функциональность, я хочу убедиться, что создаю его правильно. Существуют ли какие-либо вопиющие принципы React/подходы к форматированию CSS, которые

  4. Я передаю начальные значения своим группам кнопок дважды — один раз в параметрах, переданных компоненту ToolButtonGroup, а также один раз в качестве начального состояния в starterComponent. Как убрать это дублирование?

Любая помощь приветствуется - это важный компонент для меня, чтобы правильно настроить веб-приложение графических инструментов, которые я создаю. Если его функциональность не работает должным образом, у меня наверняка возникнут проблемы в другом месте.


person Canovice    schedule 13.04.2018    source источник


Ответы (1)


Большая часть ваших вопросов может быть больше связана с codereview.stack, но у меня есть несколько мыслей по этому поводу.

1. Еще не грид-мастер, а непосредственный дочерний грид (элемент-контейнер с классом "диаграмма-сетка-контейнер") является элементом с классом "кнопки-контейнер". Сразу же вы должны задаться вопросом, что если что-то определено в этом классе css. Второе наблюдение: просмотрев эту страницу документа , это то, что вам не хватает правила grid-area, и мне интересно, предназначена ли поддержка «gridID» для соответствия этому.

2. Если вы ожидаете, что позже к этому обработчику будет добавлена ​​дополнительная локальная логика, сохраните ее. В противном случае он вам не нужен.

3. На самом деле, для ясности мне нравится, что у каждого есть свой дискретный именованный обработчик. С другой стороны, если есть целая куча этих компонентов и повторяющаяся логика, я бы, вероятно, использовал динамические имена объектов es6 Object с преобразователем, например:

    // pseudo code!
    handleChange = (key_name) => {
      return (new_value) =>
        this.setState({
          [key_name]: new_value
        })
    }

   // later ...
   handler={this.handleChange('position')} />    

4. Для вашего компонента ToolButtonGroup, если он не будет иметь собственное локальное состояние, вы должны просто сделать это функция в случае, если конструктор и оболочка-обработчик не нужны (как обсуждалось выше)

Второе замечание: необходимо ли, чтобы все реквизиты передавались под другим пространством имен («параметры»)? Кажется, это не служит никакой цели. Я действительно думаю, что это правильно, что вы указываете реквизиты для каждого экземпляра компонента в его собственном объекте, но что я сделал бы дальше, так это просто распространил бы их в JSX, а затем ссылался бы на них напрямую из this.props как указано здесь.

           <ToolButtonGroup
                {...positionButtonGroupProps}
                handler={this.handleChange('position')} />

5. Я немного не понимаю этот вопрос, потому что на самом деле я не замечаю, что реквизит value упоминается в ToolButtonGroup? Может быть, я приукрасил это. В любом случае, я бы просто прикрепил это к объекту реквизита, как описано выше.

person uncleoptimus    schedule 14.04.2018
comment
оцените обратную связь по этому поводу :) - person Canovice; 16.04.2018