简体   繁体   English

React 钩子值正确呈现但未在 addEventListener 的回调 function 中更新

[英]React hooks value renders correctly but not updated inside a callback function of addEventListener

I'm implementing infinite scroll with hooks in a functional component, I'm having an issue where I'm unable to access the updated value inside the scroll event callback function, here's my code:我在功能组件中使用钩子实现无限滚动,我遇到了一个问题,我无法访问滚动事件回调 function 中的更新值,这是我的代码:

 // Get a hook function const {useState, useEffect} = React; const initItems = ['First', 'Second','Third','Fourth','Fifth'] const Example = ({title}) => { const [posts, setPosts] = useState({ data: [], page: 1 }); console.log('FN RENDER') const handleScroll = (e) => { const { scrollHeight, scrollTop, clientHeight } = e.target const bottom = scrollHeight - scrollTop === clientHeight; if (bottom) { console.log('page', posts.page) // page stays 1 const nextPage = posts.page + 1 setPosts(p => ({ data: [...p.data, 'Append'], page: p.page + 1 })) } } useEffect(() => { console.log('USEEFFECT RENDER') setPosts(p => ({ data: initItems, page: 1 })) //using ScrollBox for demo, originally I'm handling the scroll event on the document: document.addEventListener document.getElementById("ScrollBox").addEventListener('scroll',handleScroll); return () => document.getElementById("ScrollBox").removeEventListener('scroll', handleScroll); }, []); return ( <div> <p>Page:{posts.page}</p> <div id="ScrollBox" class="scroll-box"> { posts.data.map(k=> <p>{k} </p>) } </div> </div> ); }; // Render it ReactDOM.render( <Example />, document.getElementById("react") );
 #ScrollBox{ border:1px solid red; height:100px; overflow:auto; width:400px; }
 <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>

If you look into the console, the value of page stays 1 while it is rendered correctly.如果您查看控制台, page的值在正确呈现时保持为1 I used useEffect to attach the event.我使用useEffect来附加事件。 How can I get the right updated value inside handleScroll ?如何在handleScroll中获得正确的更新值?

-- Edit -- - 编辑 -

How to get the updated value inside the callback of addEventListener ?如何在addEventListener的回调中获取更新的值? #ScrollBox is for the question demo, I instead need to detect scroll on document , which is the reason I'm using the event listener. #ScrollBox用于问题演示,我需要检测document上的滚动,这就是我使用事件侦听器的原因。

The useEffect function only fires when the second parameter has changed. useEffect function 仅在第二个参数发生更改时触发。 Since you have an empty second parameter, it will never update, and since it never updates, your event handler holds on to the stale closure from the first render no matter how many times you update the state.由于您有一个空的第二个参数,因此它永远不会更新,并且由于它永远不会更新,因此无论您更新 state 多少次,您的事件处理程序都会从第一次渲染开始保持陈旧的关闭。

You can fix your code by passing the the event listener directly inside the render function rather than in useEffect .您可以通过在渲染 function 而不是在useEffect中直接传递事件侦听器来修复您的代码。 You should not do direct DOM manipulation in react anyway.无论如何,您都不应该在 react 中进行直接的 DOM 操作。

 // Get a hook function const {useState, useEffect} = React; const initItems = ['First', 'Second','Third','Fourth','Fifth'] const Example = ({title}) => { const [posts, setPosts] = useState({ data: [], page: 1 }); console.log('FN RENDER') const handleScroll = (e) => { const { scrollHeight, scrollTop, clientHeight } = e.target const bottom = scrollHeight - scrollTop === clientHeight; if (bottom) { console.log('page', posts.page) // page stays 1 const nextPage = posts.page + 1 setPosts(p => ({ data: [...p.data, 'Append'], page: p.page + 1 })) } } useEffect(() => { console.log('USEEFFECT RENDER') // <:-- No event handler here --> setPosts(p => ({ data, initItems: page, 1 })) }; []): return ( <div> <p>Page.{posts.page}</p> <.-- NOTE THE EVENT HANDLER HERE --> <div id="ScrollBox" class="scroll-box" onScroll={handleScroll} > { posts;data;map(k=> <p>{k} </p>) } </div> </div> ). }, // Render it ReactDOM.render( <Example />; document.getElementById("react") );
 #ScrollBox{ border:1px solid red; height:100px; overflow:auto; width:400px; }
 <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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在反应中调用 addEventListener 内的 addEventListener 回调 function - call addEventListener inside addEventListener callback function in react 反应钩子没有从库事件(FabricJS)的回调 function 中返回更新的 state 值 - React hooks not returning updated state values inside callback function from library events (FabricJS) React:事件回调中的道具值未更新 - React: Prop value inside event callback not updated 为什么在回调函数中反应状态(数组)为空? 为什么不使用来自外部范围的更新值? - Why is react state(array) empty inside callback function? Why is it not using the updated value from outer scope? 如何使用 React Hooks 将 state 值传递给回调 function - How to pass state value to a callback function using React Hooks 开玩笑 | 断言在 addEventListener 回调中调用了 function - JEST | Assert a function was called inside addEventListener callback 回调内部的值不会在每次函数调用时更新 - Value inside of callback is not being updated on each function call react js无法在setState回调function中获取更新值 - react js cannot get updated value in setState callback function React Hooks-无法获取更新的状态值 - React Hooks - Unable to get updated state value 使用钩子做出反应时没有得到更新的 state 值? - not getting updated state value in react using hooks?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM