反应:[标签]-[输入]-[编辑按钮]-[保存按钮-(隐藏)]

React: [Label]-[input]-[edit btn]-[save btn-(hidden)]

如标题所述,我得到了一个简单的 crud 操作,我可以在 useEffect/useState 挂钩方面使用一些帮助来了解如何实现。

我已将输入设置为默认禁用,通过占位符显示之前的值。然后通过 useState/useEffect 挂钩更新状态。另外,第二个按钮(保存)默认设置为隐藏。

目标:

JSX:

<label className="col">
  <div className="row">
    <p className="bold nowrap inline-value-title" >Test Name:&nbsp; </p>
    <input 
      id="display-name-change"
      type="text"
      className="form-reset inline-input"
      onChange={(e) => setDisplayName(e.target.value)}
      value={displayName}
      placeholder={user.displayName}
      disabled
    />
    <button type="button" className="inline-button edit-val-btn">
      <FontAwesomeIcon icon={faPenToSquare}  />
    </button>
    <button type="button" className="hidden inline-button save-val-btn">.  
      <FontAwesomeIcon icon={faCircleCheck}  />
    </button>
  </div>
</label>

我的 Javascript:(你可能会说它仍然很香草,我认为这就是问题所在)...

const editValueBtns = document.querySelectorAll('.edit-val-btn');
const saveValueBtns = document.querySelectorAll('.save-val-btn');

useEffect(() => {
    editValueBtns.forEach((button) => {
        button.addEventListener('click', (e) => {
            //e.preventDefault()
            //console.log(e)
            button.classList.add('hidden')
            button.nextSibling.classList.remove('hidden')
            // console.log(button.parentElement.children[1])
            button.parentElement.children[1].removeAttr("disabled") ;
        })
    })

    saveValueBtns.forEach((button) => {
        button.addEventListener('click', (e) => {
            //e.preventDefault()
            //console.log(e)
            button.classList.add('hidden')
            button.previousSibling.classList.remove('hidden')
            //console.log(button.parentElement.children[1])
            button.parentElement.children[1].addAttr("disabled") ;
        })
    })
}, []);

小调整.. 似乎记录控制台阻止了它做它所做的事情。还从每个 'click' 后的括号中删除了 e。 addAttr 和 removeAttr 也被替换了......其余的功能可以放在任何一个侦听器中..

编辑: 添加了第二个输入,它似乎只适用于第一个输入.... ...是的,我在自言自语。

编辑 2: 它工作正常,直到页面刷新...删除依赖项数组以使其每次都能工作。我觉得我仍然需要一个清理函数,但我不能只将事件侦听器放入一个函数中,可以吗?真的,如果您正在阅读这篇文章,我会喜欢一些更有经验的输入...:)

useEffect(() => {
    editValueBtns.forEach((button) => {
        button.addEventListener('click', () => {
            button.classList.add('hidden')
            button.nextSibling.classList.remove('hidden')
            button.parentElement.children[1].disabled = false ;
        })
    })

    saveValueBtns.forEach((button) => {
        button.addEventListener('click', () => {
            button.classList.add('hidden')
            button.previousSibling.classList.remove('hidden')
            button.parentElement.children[1].disabled = true ;
        })
    })
});

我看到了你的 vanilla js 方式,并提高了你的反应方式。在 React 中,您不必使用 document.querySelector、previousSibling、parentElement、classList.add、classList.remove、addAttr 或 button.addEventListener。请参阅 CodeSandbox 或以下的解决方案:

App.jsx

import { Row } from "./components/Row";
import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <Row placeholder="input 1" />
      <Row placeholder="input 2" />
      <Row placeholder="input 3" />
    </div>
  );
}

Row.jsx

import { useState } from "react";

export const Row = ({ defaultValue, placeholder }) => {
  const [value, setValue] = useState(defaultValue);
  const [disabled, setDisabled] = useState(true);

  const handleEditClick = () => {
    setDisabled(false);
  };

  const handleSaveClick = () => {
    setDisabled(true);
    // save logic goes here
  };

  return (
    <label className="col">
      <div className="row">
        <p className="bold nowrap inline-value-title">Test Name:</p>
        <input
          type="text"
          className="form-reset inline-input"
          onChange={(e) => {
            setValue(e.target.value);
          }}
          value={value}
          placeholder={placeholder}
          disabled={disabled}
        />
        {disabled && (
          <button
            type="button"
            onClick={handleEditClick}
            className="inline-button edit-val-btn"
          >
            edit
          </button>
        )}
        {!disabled && (
          <button
            type="button"
            onClick={handleSaveClick}
            className="hidden inline-button save-val-btn"
          >
            save
          </button>
        )}
      </div>
    </label>
  );
};