获取侦听器内 useState 的值

问题描述 投票:0回答:1

我想显示从 DIV 上的单击事件获得的坐标列表。我希望监听器仅在单击按钮时起作用。

export function AppRestoration() {

  const [state, setState] = useState(false)
  const [coordinates, setClickCoord] = useState<any[]>([])

  const handleClick = (event) => {

    // I need to get access to coordinates here (to filter them), but it is always an empty array
    console.log(coordinates)
    setClickCoord(prevCoordinates => [...prevCoordinates, event.clientX]);
  }

  React.useEffect(() => {
    if (state) {

      const handleGlobal = (event) => {
        handleClick(event)
      }
      document.getElementById("alex")?.addEventListener('click', handleGlobal)
      return () => document.getElementById("alex")?.removeEventListener('click', handleGlobal)
    }
  }, [state])

  return (
    <div>
      <div id="alex" style={{ width: '200px', height: '200px', backgroundColor:'red' }}>ici</div>
      <button onClick={() =>setState(prev => !prev)}>{state ? 'clicked' : 'not'}</button>
      <SecondComponent
        secondCParam={coordinates} />
    </div>
  )
}

问题是:在handleClick(event)中我无法过滤“坐标”,它始终是一个空数组。要刷新它,我必须单击该按钮,因此请再处理一次。如何避免?

reactjs events react-hooks
1个回答
0
投票

您应该避免在 React 中使用原生 JS 事件监听器。以下是如何重构代码以使用 React 方法获得相同结果的方法:

export function AppRestoration() {

  const [state, setState] = useState(false)
  const [coordinates, setClickCoord] = useState<any[]>([])

  return (
    <div>
      <div id="alex" onClick={() => {
   if (state) setClickCoord(prevCoordinates => [...prevCoordinates, event.clientX]);
}} style={{ width: '200px', height: '200px', backgroundColor:'red' }}>ici</div>
      <button onClick={() => setState(!state)}>{state ? 'clicked' : 'not'}</button>
      <SecondComponent
        secondCParam={coordinates} />
    </div>
  )
}

但是,如果您想尝试事件侦听器并使用此模式,您可以像这样重构

handleClick

const handleClick = (event) => {
    // I need to get access to coordinates here (to filter them), but it is always an empty array
    setClickCoord(prevCoordinates => {
      console.log(prevCoordinates)
      return [...prevCoordinates, event.clientX]);
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.