Установите значение по умолчанию в объекте состояния в React Typescript

#reactjs #typescript

Вопрос:

В данный момент в моем компоненте я устанавливаю значение по умолчанию «null», но я пытаюсь по умолчанию присвоить значение активных состояний первому объекту в объектах, который является частью состояния, немного запутавшись.

код до сих пор:

 import React from 'react';

interface ActiveObject {
    id: number;
    title: string;
    function(index: number): void;
};

interface ButtonGroupState {
    activeObject: ActiveObject | null;
    objects: ActiveObject[];
};

const ButtonGroup: React.FunctionComponent = () => {

    const [active, setActive] = React.useState<ButtonGroupState>({
        activeObject: null,
        objects: [{
            id: 1,
            title: '1 Week',
            function(index: number) {
                setActive({ ...active, activeObject: active.objects[index] })
            }

        }, {
            id: 2,
            title: '1 Month',
            function(index: number) {
                setActive({ ...active, activeObject: active.objects[index] })

            }
        }, {
            id: 3,
            title: '3 Months',
            function(index: number) {
                setActive({ ...active, activeObject: active.objects[index] })

            }
        }]
    })

    const toggleActiveStyles = (index: number) => {
        if (active.objects[index] === active.activeObject) {
            return "btn-active"
        } else {
            return " btn-plain"
        }
    }

    return (
        <> <div className="wrapper">
            {active.objects.map((inner, index) => 
                <button type="button" className={toggleActiveStyles(index)} onClick={() => inner.function(index)} key={inner.id}>{inner.title}</button>
            )}
        </div>
        </>

    )
}

export default ButtonGroup;
 

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

1. в чем ваша проблема?

2. В данный момент активное состояние по умолчанию равно нулю, как бы я изменил активное состояние по умолчанию на первый элемент/объект?

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

4. В штате есть объекты с идентификатором, названием и т. Д

5. Активный объект: объекты[0] 🤔

Ответ №1:

Я предлагаю вам переместить объекты в переменную и установить для ее первого элемента значение ActiveObject

 import React from 'react';

interface ActiveObject {
    id: number;
    title: string;
    function(index: number): void;
};

interface ButtonGroupState {
    activeObject: ActiveObject | null;
    objects: ActiveObject[];
};

const ButtonGroup: React.FunctionComponent = () => {
    const objectsArray = [{
            id: 1,
            title: '1 Week',
            function(index: number) {
                setActive({ ...active, activeObject: active.objects[index] })
            }

        }, {
            id: 2,
            title: '1 Month',
            function(index: number) {
                setActive({ ...active, activeObject: active.objects[index] })

            }
        }, {
            id: 3,
            title: '3 Months',
            function(index: number) {
                setActive({ ...active, activeObject: active.objects[index] })

            }
        }];

    const [active, setActive] = React.useState<ButtonGroupState>({
        activeObject: objectsArray[0],
        objects: objectsArray
    })

    const toggleActiveStyles = (index: number) => {
        if (active.objects[index] === active.activeObject) {
            return "bp-active"
        } else {
            return " btn-plain"
        }
    }

    return (
        <> <div className="wrapper">
            {active.objects.map((inner, index) => 
                <button type="button" className={toggleActiveStyles(index)} onClick={() => inner.function(index)} key={inner.id}>{inner.title}</button>
            )}
        </div>
        </>

    )
}

export default ButtonGroup;
 

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

1. Это на самом деле имеет больше смысла, спасибо!

Ответ №2:

Вы можете либо дублировать данные первого элемента в качестве начального состояния. Примечание: разложение определения массива на множители было бы оптимизацией.

 const ButtonGroup: React.FunctionComponent = () => {
  const [active, setActive] = React.useState<ButtonGroupState>({
    activeObject: {
      id: 1,
      title: '1 Week',
      function(index: number) {
        setActive({ ...active, activeObject: active.objects[index] })
      }
    },
    objects: [{
      id: 1,
      title: '1 Week',
      function(index: number) {
        setActive({ ...active, activeObject: active.objects[index] })
      }
    }, {
      id: 2,
      title: '1 Month',
      function(index: number) {
        setActive({ ...active, activeObject: active.objects[index] })

      }
    }, {
      id: 3,
      title: '3 Months',
      function(index: number) {
        setActive({ ...active, activeObject: active.objects[index] })
      }
    }]
  });
 

или используйте useEffect крючок, чтобы установить его на начальный рендеринг.

 React.useEffect(() => {
  setActive(active[0]);
}, []);
 

Примечание

Похоже, у вас есть логическая ошибка с функциями, в которых они будут иметь устаревшие вложения active и activeObject состояние. Это может быть нормально active.object , если он никогда не обновляется. Поскольку это одна и та же функция для каждого элемента, вам следует учесть это, чтобы ваш код был более СУХИМ, и использовать функциональное обновление.

Вы, вероятно, также не знаете, что дублировать состояние. Просто сохраните активный идентификатор (или индекс) и укажите его в своем коде при доступе/передаче реквизитов.

 const setActive = (index: number) => {
  setActive(active => ({
    ...active,
    activeObject: index,
  }));
}
 

Затем используйте/передайте setActive как опору там, где вам нужно.

 ...
activeObject={active.objects[active.activeObject]}
setActive={setActive}
...
 

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

1. Спасибо, что я так думал, но, думаю, я слишком много думал об этом, поэтому запутался.