Я использую хуки для поддержания состояния массива, содержащего данные вместе с компонентом кнопки. Этот компонент имеет обработчик событий onClick
.
const MyComponent = () => {
const initialData = [{ "field": "foo", "button": getButton("foo") }];
const [ data, setData ] = useState(initialData);
const getButton = (entry) => <Button onClick={() => doStuff(entry)}>Hello</Button>
const doStuff = (entry) => console.log(data)
const addData = () => {
const moreData = { "field": "bar", "button": getButton("bar") }
setData([ ...data, moreData ])
const evenMoreData = { "field": "roll", "button": getButton("roll") }
setData([ ...data, evenMoreData ])
}
const myList = data.map(d => <>{d.field} {d.button}</>)
return (
<>
{myList}
<Button onClick={() => doStuff('foo')}>Hi</Button>
<Button onClick={() => addData()}>Add Data</Button>
</>
)
}
Этот data
корректно отображается в myList
. Когда я нажимаю кнопку в foo
, она вызывает doStuff
, которая печатает data
как пустой массив (как если бы это был моментальный снимок во времени до добавления foo
). Если я нажимаю кнопку в bar
, она печатает массив с foo
. Если я нажимаю кнопку в roll
, она печатает массив, содержащий только foo
и bar
.
Однако, если я добавлю идентичную кнопку за пределами myList
, она может напечатать data
правильно содержит все foo
, bar
и roll
. Почему это так, и как я могу обойти это?
Мой текущий обходной путь включает useEffect
и введение еще одного хука для поддержания состояния нажатой кнопки, но это не кажется мне очень элегантным, разбивая логику c далеко от того места, где вы ожидаете.