禁用按钮永久化

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

Disable Button for good

问题

你可以在React中禁用按钮,当登录用户是会员时吗?
当我使用disabled属性时,它可以从开发者工具中删除,按钮会再次激活。

请帮助我

我希望按钮在登录用户是会员时保持禁用。即使从开发者工具中删除disabled属性,它仍然应保持不活跃。

英文:

Can I disable a Button in react when the login user is a member?
When I used the disabled attribute, it can be deleted from developer tools and the button is active again.

Please help me

I want the button to stay disabled when the login user is a member. Even after deleting the disabled attribute from developer tools, it shall still be inactive.

答案1

得分: 4

以下是翻译好的部分:

你可以使用 disabled 属性来禁用按钮,但这不会阻止用户在开发工具中移除 disabled 属性并重新启用按钮。为了避免这种情况,你还应该使用 disabled 值来有条件地处理按钮的点击事件监听器。

例如:

import { useState } from "react";

export default function App() {
  const [disabled, setDisabled] = useState(false);
  const handleClick = (e) => {
    console.log(e.target);
  };

  return (
    <div className="App">
      <button onClick={() => setDisabled((disabled) => !disabled)}>
        禁用按钮
      </button>
      <button disabled={disabled} onClick={disabled ? null : handleClick}>
        点击
      </button>
    </div>
  );
}

这样,即使用户移除了 disabled 属性,按钮也不会附加任何点击处理程序。

另外,你还可以将 pointer-events 样式设置为 none

例如:

import { useState } from "react";

export default function App() {
  const [disabled, setDisabled] = useState(false);

  return (
    <div className="App">
      <button onClick={() => setDisabled((disabled) => !disabled)}>
        禁用按钮
      </button>
      <button
        disabled={disabled}
        style={disabled ? { pointerEvents: "none" } : {}}
        onClick={console.log}
      >
        点击
      </button>
    </div>
  );
}

这样,即使用户在开发工具中移除样式和禁用属性,也可以阻止按钮被点击。

你可以在这里查看完整的示例:codesandbox.io

英文:

You can use the disabled prop to disable the button, but this will not prevent the user from removing the disabled attribute in the dev tools and enabling the button again. To avoid this, you should also use the disabled value to conditionally handle the click event listener from the button.

For example:

import { useState } from &quot;react&quot;;

export default function App() {
  const [disabled, setDisabled] = useState(false);
  const handleClick = (e) =&gt; {
    console.log(e.target);
  };

  return (
    &lt;div className=&quot;App&quot;&gt;
      &lt;button onClick={() =&gt; setDisabled((disabled) =&gt; !disabled)}&gt;
        disable button
      &lt;/button&gt;
      &lt;button disabled={disabled} onClick={disabled ? null : handleClick}&gt;
        click
      &lt;/button&gt;
    &lt;/div&gt;
  );
}

This way, even if the user removes the disabled attribute, the button will not have any click handler attached to it.

<hr />
<h1>UPDATED ANSWER</h1>

Alternatively, you can set pointer-events style to none.

For example:

import { useState } from &quot;react&quot;;

export default function App() {
  const [disabled, setDisabled] = useState(false);

  return (
    &lt;div className=&quot;App&quot;&gt;
      &lt;button onClick={() =&gt; setDisabled((disabled) =&gt; !disabled)}&gt;
        disable button
      &lt;/button&gt;
      &lt;button
        disabled={disabled}
        style={disabled ? { pointerEvents: &quot;none&quot; } : {}}
        onClick={console.log}
      &gt;
        click
      &lt;/button&gt;
    &lt;/div&gt;
  );
}

This way, you can stop the button from being clicked even if the user removes the style and the disabled property in the dev tools.

You can see the whole example here: codesandbox.io

答案2

得分: 2

如果您想根据登录用户是否为会员来禁用React中的按钮,并防止用户通过开发者工具启用它,您需要以更安全的方式处理按钮的禁用状态。实现这一目标的一种方法是通过在组件的状态中管理按钮的禁用状态,或者使用Redux。

以下是如何实现这一点的示例:

  • 假设您有一些状态来指示登录用户是否是会员。为了演示,我将使用一个名为isMember的布尔变量来表示这个状态。

  • 根据isMember的值初始化按钮的禁用状态。

  • 使用React的生命周期方法或React hooks(例如useEffect)来监视isMember值的变化,并相应地更新按钮的禁用状态。

  • 当按钮被点击时,只有当它没有禁用时才执行所需的操作。

英文:

If you want to disable a button in React based on whether the login user is a member and prevent users from enabling it via developer tools, you need to handle the button's disabled state in a more secure way. One way to achieve this is by managing the button's disabled state within your component's state or using Redux.

Here's an example of how you can implement this:

  • Assuming you have some state that indicates whether the login user is
    a member or not. For demonstration purposes, I'll use a boolean
    variable called isMember to represent this state.

  • Initialize the button's disabled state based on the isMember value.

  • Use React's lifecycle methods or React hooks (e.g., useEffect) to
    monitor changes to the isMember value and update the button's
    disabled state accordingly.

  • When the button is clicked, perform the desired action only if it's
    not disabled.

答案3

得分: -3

Here's the translated code:

**永久禁用按钮**

您可以像这样禁用元素并删除按钮的点击事件监听器以便在他们通过开发工具启用它或尝试更改按钮状态时按钮不起作用因为它指向了一个虚假的函数最后您可以添加一个突变观察器来使按钮永远禁用

```javascript
import React, { useState, useRef, useEffect } from "react";
import "./App.css";

function App() {
  const elementRef = useRef();

  const [isDisabled, setDisabled] = useState(false);
  const handleClick = (e) => {
    if (!isDisabled) {
      console.log("我是原始的点击处理程序");
    }
  };

  useEffect(() => {
    elementRef.current.addEventListener("click", handleClick);
  }, []);

  const handleDisabled = () => {
    if (!isDisabled) {
      setDisabled(true);
      elementRef.current.disabled = true;
      delete elementRef.current.removeEventListener("click", handleClick);
      elementRef.current.onclick = () => console.log("我是虚假的点击处理程序");

      var config = {
        attributes: true,
        childList: true,
        characterData: true,
      };

      // 观察器以阻止通过开发工具启用元素。
      var observer = new MutationObserver(function (mutations) {
        mutations.forEach((record) => {
          // 在每次迭代中,可以访问单个突变。

          // 在这种情况下,如果变异的类型是属性,则运行以下块。
          // 一个变异可以有多种类型。
          if (record.type === "attributes") {
            const changedAttrName = record.attributeName;

            if (changedAttrName === "disabled") {
              observer.disconnect(); // 关闭观察器;
              record.target.setAttribute("disabled", true);
              observer.observe(elementRef.current, config); // 再次打开
            }
          }
        });
      });

      observer.observe(elementRef.current, config);
    }
  };

  return (
    <div>
      <button onClick={handleDisabled}>禁用按钮</button>
      <button ref={elementRef}>点击</button>
    </div>
  );
}

export default App;

另外,您还可以创建一个自定义钩子,使用它的引用和突变观察器来禁用元素。

import { useState, useCallback } from "react";
export function useForceDisabled(elementRef) {
  const [isObserving, setObserving] = useState(false);
  var config = {
    attributes: true,
    childList: true,
    characterData: true,
  };

  // 观察器以阻止通过开发工具启用元素。
  var observer = new MutationObserver(function (mutations) {
    mutations.forEach((record) => {
      // 在每次迭代中,可以访问单个突变。

      // 在这种情况下,如果变异的类型是属性,则运行以下块。
      // 一个变异可以有多种类型。
      if (record.type === "attributes") {
        const changedAttrName = record.attributeName;

        if (changedAttrName === "disabled") {
          observer.disconnect(); // 关闭观察器;
          record.target.setAttribute("disabled", true);
          observer.observe(elementRef.current, config); // 再次打开
        }
      }
    });
  });

  const observe = useCallback(() => {
    if (!isObserving) {
      observer.observe(elementRef.current, config);
      setObserving(true);
    }
  }, []);

  const disconnect = useCallback(() => {
    if (isObserving) {
      observer.disconnect();

      setObserving(false);
    }
  }, []);

  return [observe, disconnect];
}

用法:

const [observe, disconnect] = useForceDisabled(elementRef);
// 在需要禁用元素的函数中调用observe
observe();

最重要的是:在客户端禁用按钮不足以保护您的应用,务必在服务器端处理他们使用任何方法启用按钮并尝试发送数据的情况,您需要阻止所有不受欢迎的请求,并始终检查用户是否可以执行操作。

您可以在https://codedamn.com/online-compiler/reactjs上通过复制粘贴尝试此代码。


<details>
<summary>英文:</summary>
**Disabled button Forever**
you can **disabled the element** and **remove the click event listener** for the button like this when they **enabling** it via dev tools or they try to **change the state** the button dont work because **it point to a fake function** and finally you can add an **Mutation Observer** to make the **button Disabled for Forever**
import React, { useState, useRef, useEffect } from &quot;react&quot;;
import &quot;./App.css&quot;;
function App() {
const elementRef = useRef();
const [isDisabled, setDisabled] = useState(false);
const handleClick = (e) =&gt; {
if (!isDisabled) {
console.log(&quot;i am the orginal click handler&quot;);
}
};
useEffect(() =&gt; {
elementRef.current.addEventListener(&quot;click&quot;, handleClick);
}, []);
const handleDisabled = () =&gt; {
if (!isDisabled) {
setDisabled(true);
elementRef.current.disabled = true;
delete elementRef.current.removeEventListener(&quot;click&quot;, handleClick);
elementRef.current.onclick = () =&gt;
console.log(&quot;i am the fake click handler&quot;);
var config = {
attributes: true,
childList: true,
characterData: true
};
// Observer to block the element to be enabled from dev tools.
var observer = new MutationObserver(function (mutations) {
mutations.forEach((record) =&gt; {
// In each iteration an individual mutation can be accessed.
// In this case if the type of mutation is of attribute run the following block.
// A mutation could have several types.
if (record.type === &quot;attributes&quot;) {
const changedAttrName = record.attributeName;
if (changedAttrName === &quot;disabled&quot;) {
observer.disconnect(); // turn observer off;
record.target.setAttribute(&quot;disabled&quot;, true);
observer.observe(elementRef.current, config); // turn back on
}
}
});
});
observer.observe(elementRef.current, config);
}
};
return (
&lt;div&gt;
&lt;button onClick={handleDisabled}&gt;disable button&lt;/button&gt;
&lt;button ref={elementRef}&gt;click&lt;/button&gt;
&lt;/div&gt;
);
}
export default App;
also you can create a **custom hook** to disabled an element using his reference with mutation observer 
import { useState, useCallback } from &quot;react&quot;;
export function useForceDisabled(elementRef) {
const [isObserving, setObserving] = useState(false);
var config = {
attributes: true,
childList: true,
characterData: true
};
// Observer to block the element to be enabled from dev tools.
var observer = new MutationObserver(function (mutations) {
mutations.forEach((record) =&gt; {
// In each iteration an individual mutation can be accessed.
// In this case if the type of mutation is of attribute run the following block.
// A mutation could have several types.
if (record.type === &quot;attributes&quot;) {
const changedAttrName = record.attributeName;
if (changedAttrName === &quot;disabled&quot;) {
observer.disconnect(); // turn observer off;
record.target.setAttribute(&quot;disabled&quot;, true);
observer.observe(elementRef.current, config); // turn back on
}
}
});
});
const observe = useCallback(() =&gt; {
if (!isObserving) {
observer.observe(elementRef.current, config);
setObserving(true);
}
}, []);
const disconnect = useCallback(() =&gt; {
if (isObserving) {
observer.disconnect();
setObserving(false);
}
}, []);
return [observe, disconnect];
}
usage 
const [observe, disconnect] = useForceDisabled(elementRef);
// call observe in function where you want to disabled the element
observe();
**THE MOST IMPORTANT** : DISABLED A BUTTON AT **CLIENT SIDE** IS NOT SUFFISANT TO PROTECT YOUR APP **BE SUR AND BE SUR AT SERVER SIDE TO HANDLE THE CASE IF THEY ENABLED THE BUTTON USING ANY METHODS AND THEY TRY TO SEND DATA, YOU NEED TO BLOCK ALL UNWANTED REQUESTS AND ALWAYS CHECK IF THE USER CAN PERFOM AN ACTION**
you can try the code at https://codedamn.com/online-compiler/reactjs by copy paste
</details>

huangapple
  • 本文由 发表于 2023年7月18日 12:46:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76709599.html
匿名

发表评论

匿名网友

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

确定