#javascript #reactjs
Вопрос:
Мне нужно найти способ использовать как переменную, объявленную внутри функционального компонента, так и часть реквизитов функционального компонента внутри функции обратного вызова в списке событий mousemove.
До сих пор у меня есть приведенный ниже код, но, похоже, реквизиты не обновляются в функции onHover.
Полный компонент немного сложнее, чем этот пример кода, но приведенный ниже пример-самый простой способ показать мою проблему. При инициализации значение в реквизитах будет равно 1, а в функции onHover оно останется 1, даже если произойдет изменение и повторная визуализация, а в других местах компонента оно показывает правильное значение 2.
Есть ли способ убедиться, что функция onHover ссылается на самую последнюю версию реквизита?
Я попытался использовать useEffect
крюк, чтобы удалить и добавить список событий, но тогда я, похоже, не могу получить доступ к variableNeededInOnHover
function FunctionalComp(props){
let variableNeededInOnHover = null;
useEffect(()=>{
window.addEventListener("mousemove", onHover, true)
return () => {
window.removeEventListener("mousemove", onHover, true)
}
}, [])
function onHover(event) {
console.log(props.value) // stays 1
console.log(variableNeededInOnHover)
}
return ( <div>{props.value}</div> ) // Updates to show a value of 2
}
Есть ли способ решить эту проблему?
Редактировать:
Я попробовал предлагаемое решение Taxel, и, похоже, variableNeededInOnHover
оно сохраняет нулевое значение, даже если я установил его значение в useEffect
крючке, имитируя метод жизненного цикла componentDidMount ().
function FunctionalComp(props){
let variableNeededInOnHover = null;
useEffect(()=>{
variableNeededInOnHover = "Non Null Value";
}, [])
useEffect(()=>{
window.addEventListener("mousemove", onHover, true)
return () => {
window.removeEventListener("mousemove", onHover, true)
}
}, [props.value])
function onHover(event) {
console.log(props.value) // stays 1
console.log(variableNeededInOnHover)
}
return ( <div>{props.value}</div> ) // Updates to show a value of 2
}
Комментарии:
1. добавление
props.value
в текущий пустой массив зависимостейuseEffect
должно помочь.2. @Taxel Я попытался добавить
props.value
его в зависимость, иprops.value
он действительно обновляется, но каким-то образомvariableNeededInOnHover
сохраняет исходноеnull
значение…3. variableNeededInOnHover необходимо объявить с помощью функции useState. В противном случае он сбрасывается до нуля при каждом рендеринге.
4. «но каким — то образом
variableNeededInOnHover
сохраняет исходное нулевое значение…» Любое «внешнее» значение должно быть объявлено как зависимость отuseEffect
, чтобы обработчики событий воссоздавались всякий раз, когда меняется одно из этих значений. Т. е. вам нужно[props.value, variableNeededInOnHover]
. reactjs.org/docs/hooks-effect.html
Ответ №1:
Я не уверен на 100%, что это решит вашу проблему, так как у вас нет возможности обновить props.value в примере. Как правило, вам нужно использовать состояние реакции для любых значений, которые будут изменены, и вы хотите вызвать повторную отправку. Реакция не будет знать о let
том, что где-то обновляется.
Я добавил пример ниже, который показывает обновляемое значение.
function FunctionalComp(props){
const [value, setValue] = React.useState(props.value);
React.useEffect(()=>{
setValue(oldValue => oldValue 1);
}, [])
React.useEffect(()=>{
window.addEventListener("mousemove", onHover, true)
return () => {
window.removeEventListener("mousemove", onHover, true)
}
}, [value])
function onHover(event) {
console.log(value) // stays 1
}
return ( <div>{value}</div> ) // Updates to show a value of 2
}
ReactDOM.render(
<FunctionalComp value={1} />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>