簡體   English   中英

我無法在 React 的事件偵聽器上從 function 更改變量

[英]I can't change variable from function on event listener in React

我有一個 window 的mousemove事件監聽器,它調用一個 function 來改變一個變量。 但是,當我將 varibale 分配給道具時,它不會改變:

  var x = null
  var y = null

  const cursor = (e) => {
    x = e.screenX + 'px'
    y = e.screenY + 'px'
    console.log(x, y)
    return x, y
  }

  window.addEventListener('mousemove', cursor)

我試圖在事件監聽器中直接更改它

( window.addEventListener('mousemove', //everything in cursor ) 但那樣我就無法訪問e變量了。

我也不能將它與 state 一起使用,因為由於某種原因它變得太遲鈍和崩潰。

我怎樣才能使這項工作? 提前致謝。

這就是我在 vscode 中看到的:

在此處輸入圖像描述

(這是在 App 組件中,變量和 ev.net 偵聽器也在 App 中。)

沙盒:https://codesandbox.io/s/vigorous-agnesi-9l1ic?file=/src/App.js

組件僅在 state 或道具更新時重新渲染。 App沒有 state 或道具,因此它永遠不會重新渲染,因此子Cursor永遠不會重新渲染。

您可以使用附加到Cursor的 ref 並直接設置 top 和 left 屬性。 請不要忘記在卸載組件時也刪除事件偵聽器。

import React, { useEffect, useRef } from "react";
import "./styles.css";
import styled from "styled-components";

const Cursor = styled.div`
  height: 30px;
  width: 30px;
  border-radius: 50%;
  border: 1.5px solid black;
  position: absolute;
`;

export default function App() {
  const posRef = useRef(null);

  const cursor = e => {
    const { clientX = 0, clientY = 0 } = e;

    posRef.current.style.left = clientX + "px";
    posRef.current.style.top = clientY + "px";

    // console.log(clientX, clientY);
  };

  useEffect(() => {
    window.addEventListener("mousemove", cursor);
    return () => window.removeEventListener("mousemove", cursor);
  }, []);

  return (
    <div className="App">
      <h1>Demo</h1>
      <Cursor ref={posRef} />
    </div>
  );
}

編輯自定義光標

編輯

正如@KirillSkomarovskiy 所指出的,使用 state 並不是導致頁面陷入困境和崩潰的原因。 我懷疑這是/是添加了多個/重復的mousemove處理程序,這些處理程序沒有被正確清理(可能通過記錄每個更新的 position 來復合)。

const Cursor = styled.div`
  height: 30px;
  width: 30px;
  border-radius: 50%;
  border: 1.5px solid black;
  position: absolute;
  transform: translate(-50%, -50%);
  top: ${props => props.yPos};
  left: ${props => props.xPos};
`;

export default function App() {
  const [pos, setPos] = useState({ x: 0, y: 0 });

  useEffect(() => {
    const cursor = e => {
      setPos({
        x: e.clientX + "px",
        y: e.clientY + "px"
      });
      // console.log(e.clientX, e.clientY);
    };
    window.addEventListener("mousemove", cursor);
    return () => window.removeEventListener("mousemove", cursor);
  }, []);

  return (
    <div className="App">
      <h1>Demo</h1>
      <Cursor xPos={pos.x} yPos={pos.y} />
    </div>
  );
}

編輯光標演示

變量xy永遠不會有效更新,因為cursor()是一個 ES6 箭頭 function,它以functional方式工作,所以如果你想將值從cursor()傳遞到xy ,那么你應該將它們視為函數出色地:

x = (callback) =>{
   return callback;
}

y = (callback) =>{
   return callback;
}

現在您可以將值傳遞給xy

const cursor = (e) => {
    x (e.screenX + 'px');
    y (e.screenY + 'px');
}

然后你的事件監聽器調用cursor(e)

window.addEventListener('mousemove', cursor);

無論你想在哪里使用xy的值,你只需要像這樣調用它們: x()y()

這就是ES6 Functional Programming的工作原理!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM