ReactJS: 刷新页面后,可拖动元素位置不同

huangapple go评论74阅读模式
英文:

ReactJS: draggable not in same position after refreshing page

问题

以下是您要的翻译部分:

I am saving the positions of my Draggables to localStorage so that they remain the same position after refreshing the page.
我正在将我的可拖动组件的位置保存到本地存储,以便在刷新页面后它们保持相同的位置。

However, after refreshing the page, they are not in the same position as before, but somewhat rightward and downward than the original position.
然而,刷新页面后,它们的位置不再与之前相同,而是比原始位置稍微向右和向下移动。

And I've just found that the values printed in the console.log() changes every time even though I didn't change the position of the component (just click on it without dragging). For example:
而且我刚刚发现,即使我没有改变组件的位置(只是单击它而不是拖动),console.log() 中打印的值每次都会发生变化。例如:

The above log is what I have after clicking the same draggable three times. The draggable should remain on the same position, but their x and y values change every time.
上面的日志是我在连续单击相同的可拖动组件三次后获得的。这些可拖动组件应该保持在相同的位置,但它们的 x 和 y 值每次都会发生变化。

App.js

function App() {
    const [myComponents, setMyComponents] = useState([]);

    // read data from localStorage
    useEffect(() => {
        const savedItems = JSON.parse(localStorage.getItem('app-data'));
        if (savedItems) {
            setMyComponents(savedItems);
        }
    }, []);

    // save data to localStorage
    useEffect(() => {
        localStorage.setItem('app-data', JSON.stringify(myComponents));
    }, [myComponents]);

    // setMyComponents to the new list with the modified item (target)
    function updatePosition(target) {
        const newComponents = myComponents.map((component) => {
            if (target.id === component.id) {
                return target;
            } else {
                return component;
            }
        });
        setMyComponents(newComponents);
        console.log("new x: " + target.x + ", new y: " + target.y);
    }

    return (
        <div>
            {myComponents.map((n) => <MyComponent myCompo={n} updatePosition={updatePosition} />)}
        </div>
    );
}

App.js

function App() {
    const [myComponents, setMyComponents] = useState([]);

    // read data from localStorage
    useEffect(() => {
        const savedItems = JSON.parse(localStorage.getItem('app-data'));
        if (savedItems) {
            setMyComponents(savedItems);
        }
    }, []);

    // save data to localStorage
    useEffect(() => {
        localStorage.setItem('app-data', JSON.stringify(myComponents));
    }, [myComponents]);

    // setMyComponents to the new list with the modified item (target)
    function updatePosition(target) {
        const newComponents = myComponents.map((component) => {
            if (target.id === component.id) {
                return target;
            } else {
                return component;
            }
        });
        setMyComponents(newComponents);
        console.log("new x: " + target.x + ", new y: " + target.y);
    }

    return (
        <div>
            {myComponents.map((n) => <MyComponent myCompo={n} updatePosition={updatePosition} />)}
        </div>
    );
}

MyComponent.js

import Draggable from 'react-draggable';

function MyComponent({myCompo, updatePosition}) {

    // update x and y of myCompo when dragging is stopped
    function handleStop(dragElement) {
        myCompo.x = dragElement.x;
        myCompo.y = dragElement.y;
        updatePosition(myCompo);
    }

    return (
        <div>
            <Draggable
              onStop={handleStop}
              defaultPosition={{x: myCompo.x, y: myCompo.y}}
              positionOffset={{ x: '-50%', y: '-50%' }}>
                <div className="someChild"></div>
            </Draggable>
        </div>
    );
}

MyComponent.js

import Draggable from 'react-draggable';

function MyComponent({myCompo, updatePosition}) {

    // update x and y of myCompo when dragging is stopped
    function handleStop(dragElement) {
        myCompo.x = dragElement.x;
        myCompo.y = dragElement.y;
        updatePosition(myCompo);
    }

    return (
        <div>
            <Draggable
              onStop={handleStop}
              defaultPosition={{x: myCompo.x, y: myCompo.y}}
              positionOffset={{ x: '-50%', y: '-50%' }}>
                <div className="someChild"></div>
            </Draggable>
        </div>
    );
}

MyComponent.css

.someChild {
    width: 240px;
    height: 200px;
    position: absolute;
    top: 50%;
    left: 50%;
}

MyComponent.css

.someChild {
    width: 240px;
    height: 200px;
    position: absolute;
    top: 50%;
    left: 50%;
}

This part of css is written before I try to store the position of the draggable. I want the component to be placed at the center of the window. Then I find position: absolute; top: 50%; left: 50%; in css and positionOffset={{ x: '-50%', y: '-50%' }} in Draggable props can help me centering the component.
这部分的 CSS 是在我尝试存储可拖动组件的位置之前编写的。我希望组件能够位于窗口的中心。然后我发现 CSS 中的 position: absolute; top: 50%; left: 50%; 和 Draggable 属性中的 positionOffset={{ x: '-50%', y: '-50%' }} 可以帮助我将组件居中。

Don't know if the problem in storing the position is related to this piece of css and positionOffset.
不知道存储位置的问题是否与这段 CSS 和 positionOffset 有关。

I have a button that add a new copy of MyComponent, and I hope the newly created MyComponent can be placed at the center before being dragged around.
我有一个按钮,可以添加一个新的 MyComponent 副本,我希望新创建的 MyComponent 在被拖动之前可以位于中心位置。

And the data in my components are stored in this format
我的组件中的数据以以下格式存储:



<details>
<summary>英文:</summary>

I am saving the positions of my Draggables to localStorage so that they remain the same position after refreshing the page.

However, after refreshing the page, they are not in the same position as before, but somewhat rightward and downward than the original position.

And I&#39;ve just found that the values printed in the `console.log()` changes every time even though I didn&#39;t change the position of the component (just click on it without dragging). For example:

new x: 153, new y: 185
new x: 221, new y: 229
new x: 184, new y: 210

The above log is what I have after clicking the same draggable three times. The draggable should remain on the same position, but their x and y values change every time.

App.js
``` react
function App() {
    const [myComponents, setMyComponents] = useState([]);
    
    // read data from localStorage
    useEffect(() =&gt; {
        const savedItems = JSON.parse(localStorage.getItem(&#39;app-data&#39;));
        if (savedItems) {
            setMyComponents(savedItems);
        }
    }, []);

    // save data to localStorage
    useEffect(() =&gt; {
        localStorage.setItem(&#39;app-data&#39;, JSON.stringify(myComponents));
    }, [myComponents]);

    // setMyComponents to the new list with the modified item (target)
    function updatePosition(target) {
        const newComponents = myComponents.map((component) =&gt; {
            if (target.id === component.id) {
                return target;
            } else {
                return component;
            }
        });
        setMyComponents(newComponents);
        console.log(&quot;new x: &quot; + target.x + &quot;, new y: &quot; + target.y);
    }

    return (
        &lt;div&gt;
            {myComponents.map((n) =&gt; &lt;MyComponent myCompo={n} updatePosition={updatePosition} /&gt;)}
        &lt;/div&gt;
    );
}

MyComponent.js

import Draggable from &#39;react-draggable&#39;;

function MyComponent({myCompo, updatePosition}) {

    // update x and y of myCompo when dragging is stopped
    function handleStop(dragElement) {
        myCompo.x = dragElement.x;
        myCompo.y = dragElement.y;
        updatePosition(myCompo);
    }

    return (
        &lt;div&gt;
            &lt;Draggabble
              onStop={handleStop}
              defaultPosition={{x: myCompo.x, y: myCompo.y}}
              positionOffset={{ x: &#39;-50%&#39;, y: &#39;-50%&#39; }}&gt;
                &lt;div className=&quot;someChild&quot;&gt;&lt;/div&gt;
            &lt;/Draggable&gt;
        &lt;/div&gt;
    );
}

MyComponent.css

.someChild {
    width: 240px;
    height: 200px;
    position: absolute;
    top: 50%;
    left: 50%;
}

This part of css is written before I try to store the position of the draggable. I want the component to be placed at the center of the window. Then I find position: absolute; top: 50%; left: 50%; in css and positionOffset={{ x: &#39;-50%&#39;, y: &#39;-50%&#39; }} in Draggable props can help me centering the component.

Don't know if the problem in storing the position is related to this piece of css and positionOffset.
I have a button that add a new copy of MyComponent, and I hope the newly created MyComponent can be placed at the center before being dragged around.

And the data in my components are stored in this format

{
    id: 0,
    body: &quot;some text&quot;,
    x: 0,
    y: 0
}

答案1

得分: 0

我找到问题所在。在函数handleStop()中,缺少了event参数。

在添加了event之后,它可以正常工作。

function handleStop(event, dragElement) {
    myCompo.x = dragElement.x;
    myCompo.y = dragElement.y;
    updatePosition(myCompo);
}
英文:

I have found where the problem is. The event argument in the function handleStop() was missing.

After adding event it works.

function handleStop(event, dragElement) {
    myCompo.x = dragElement.x;
    myCompo.y = dragElement.y;
    updatePosition(myCompo);
}

huangapple
  • 本文由 发表于 2023年2月26日 21:40:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75572377.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定