Last active
January 12, 2023 19:03
-
-
Save evgeniyworkbel/7c7267070c4a29fc91545f0dadbb212b to your computer and use it in GitHub Desktop.
Курс "JS: React Hooks"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-check | |
/* eslint no-param-reassign: ["error", { "props": false }] */ | |
import React from 'react'; | |
import { useImmer } from 'use-immer'; | |
import cn from 'classnames'; | |
// BEGIN (write your solution here) | |
const Button = (props) => { | |
const { id, active, setActive } = props; | |
const [clickesCount, setCount] = useImmer(0); | |
const classes = cn('btn', `btn-${id === active ? 'success' : 'primary'}`, 'm-1'); | |
const handleClick = (clickedId) => (ev) => { | |
ev.preventDefault(); | |
setCount(clickesCount + 1); | |
setActive(clickedId); | |
}; | |
return ( | |
<button className={classes} type="button" onClick={handleClick(id)}>{clickesCount}</button> | |
); | |
}; | |
const Buttons = (props) => { | |
const { count } = props; | |
const buttonsCount = count ?? 3; | |
const [activeButtonId, setActiveButtonId] = useImmer(null); | |
const ids = []; | |
for (let i = 0; i < buttonsCount; i += 1) { | |
ids.push(i); | |
} | |
return ( | |
<> | |
{ids.map((id) => ( | |
<Button | |
key={id} | |
id={id} | |
active={activeButtonId} | |
setActive={setActiveButtonId} | |
/> | |
))} | |
</> | |
); | |
}; | |
export default Buttons; | |
// END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-check | |
/* eslint no-param-reassign: ["error", { "props": false }] */ | |
import React from 'react'; | |
import { useImmer } from 'use-immer'; | |
import cn from 'classnames'; | |
// BEGIN | |
const renderButton = (index, count, activeIndex, handleClick) => { | |
const className = cn('btn m-1', { | |
'btn-primary': activeIndex !== index, | |
'btn-success': activeIndex === index, | |
}); | |
return ( | |
<button | |
key={index} | |
type="button" | |
className={className} | |
onClick={handleClick} | |
> | |
{count} | |
</button> | |
); | |
}; | |
const Buttons = ({ count = 3 }) => { | |
const initButtonsState = { | |
active: null, | |
counts: Array(count).fill(0), | |
}; | |
const [buttonsState, updateButtonsState] = useImmer(initButtonsState); | |
const generateHandler = (index) => () => { | |
updateButtonsState((state) => { | |
state.active = index; | |
state.counts[index] += 1; | |
}); | |
}; | |
const { active, counts } = buttonsState; | |
return counts.map((buttonCount, index) => ( | |
renderButton(index, buttonCount, active, generateHandler(index)) | |
)); | |
}; | |
export default Buttons; | |
// END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Buttons.jsx | |
Реализуйте и экспортируйте по умолчанию компонент <Buttons />, который отрисовывает кнопки со значением счетчика. | |
В компоненте необходимо реализовать следующее поведение: | |
Текущее значение счетчика каждой кнопки — это строка внутри тега button. | |
Клик по кнопке должен увеличивать значение счетчика на единицу, не затрагивая при этом другие счетчики. | |
Компонент должен принимать пропс count, который определяет количество кнопок. Значение по умолчанию: 3. | |
Для оформления внешнего вида кнопок используйте библиотеку bootstrap (подключена к испытанию). | |
Последняя нажатая кнопка меняет цвет (с помощью класса). Классы в примерах ниже. | |
Примеры | |
Кнопки с нулевым значением счетчика: | |
<button class="btn btn-primary m-1" type="button">0</button> | |
<button class="btn btn-primary m-1" type="button">0</button> | |
<button class="btn btn-primary m-1" type="button">0</button> | |
Кнопки на которые нажимали. Последняя была вторая (btn-primary => btn-success): | |
<button class="btn btn-primary m-1" type="button">3</button> | |
<button class="btn btn-success m-1" type="button">1</button> | |
<button class="btn btn-primary m-1" type="button">2</button> | |
Подсказки | |
Решите эту задачу, используя функциональные компоненты и хуки | |
Используйте хук useImmer для управления состоянием https://github.com/immerjs/use-immer | |
Документация по хукам на русском языке: https://ru.reactjs.org/docs/hooks-intro.html | |
Статья "Как Immer покоряет React": https://ru.hexlet.io/blog/posts/kak-immer-pokoryaet-react |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment