Итак, у меня есть этот бит кода, который работает не так, как ожидалось. Текущий фокус был установлен с помощью useState () на родительском компоненте, следовательно, это переменная состояния. Однако, когда значение currentFocus изменяется в родительском элементе, переменная focus здесь сама по себе не обновляется. Я ожидал бы, что рендеринг родительского компонента, который, в свою очередь, рендерит этот компонент, вызовет изменение значения foucs.
import React, { useRef, useEffect, useState } from 'react';
const CookieDetails = props => {
const {
name,
cost,
value,
numOwned,
onMouseClick,
cookieId,
currentFocus,
} = props;
let cookieInfoRef = useRef(null);
//My focus doesnt change even if I change currentFocus in parent component
const [focus, setFocus] = useState(currentFocus);
useEffect(() => {
console.log('currentFocus', currentFocus);
console.log('focus', focus);
console.log('cookieID', cookieId);
if (cookieInfoRef.current && cookieId === focus) {
console.log('current', cookieInfoRef.current);
cookieInfoRef.current.focus();
}
}, [focus]);
return (
<React.Fragment>
<button
onClick={onMouseClick}
ref={cookieId === focus ? cookieInfoRef : null}
>
<h3>{name}</h3>
<p>Cost:{cost}</p>
<p>Value:{value}</p>
<p>Owned:{numOwned}</p>
</button>
</React.Fragment>
);
};
export default CookieDetails;
Теперь я могу решить эту проблему, выполнив следующие действия:
import React, { useRef, useEffect, useState } from 'react';
const CookieDetails = props => {
const {
name,
cost,
value,
numOwned,
onMouseClick,
cookieId,
currentFocus,
} = props;
let cookieInfoRef = useRef(null);
useEffect(() => {
console.log('currentFocus', currentFocus);
console.log('cookieID', cookieId);
if (cookieInfoRef.current && cookieId === currentFocus) {
console.log('current', cookieInfoRef.current);
cookieInfoRef.current.focus();
}
});
return (
<React.Fragment>
<button
onClick={onMouseClick}
ref={cookieId === currentFocus ? cookieInfoRef : null}
>
<h3>{name}</h3>
<p>Cost:{cost}</p>
<p>Value:{value}</p>
<p>Owned:{numOwned}</p>
</button>
</React.Fragment>
);
};
export default CookieDetails;
Но я хотел запускать ловушку useEffect только при обновлении focus / currentFocus, а не после каждого рендера. , Так почему это происходит? Чего мне не хватает, чтобы понять здесь.
Также ранее я заметил, что если вы сделали что-то подобное, функция handleStuff всегда использует начальное значение 100 (то есть всегда 100 + 10) вместо увеличения на 10 при каждом нажатии клавиши. Я могу решить эту проблему, удалив пустой [] в качестве второго аргумента в useEffect. Однако я ожидал, что handleStuff по-прежнему будет обновляться с использованием самого последнего значения, учитывая, что eventListner уже был добавлен при первоначальном рендеринге, а при втором нажатии клавиши он должен добавить 10 к 110 вместо 100, но он продолжает использовать значение начального состояния 100 вместо. Почему вы должны очистить старого слушателя и добавлять нового каждый раз, чтобы он работал?
[value, setValue] = useState(100)
handleStuff = (event) => {
setValue(value+10)
}
useEffect(() => {
window.addEventListener('keydown', handleStuff)
return () => {
window.removeEventListener('keydown', handleStuff)
}
},[]);
Я не особо заинтересован в решениях, я действительно заинтересован в понимании того, как перехватчики useEffect () и useState () работают в этих условиях.