#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. Спасибо, что я так думал, но, думаю, я слишком много думал об этом, поэтому запутался.