next.js 为什么React没有取消设置我的模态中表单输入的值?

alen0pnh  于 2023-01-20  发布在  React
关注(0)|答案(1)|浏览(112)

我正在使用Next和Tailwind/Daisy UI。
下面页面的代码将从API端点获取一个JSON对象,并呈现一个源系统的顶层表和一个附加域的底层表。单击顶层表中的一行,将第二个表过滤到相关域。这一切都很好。我还有一个模态,将用于创建新的源系统或编辑现有的源系统。[Edit]和[Create]按钮调用相同的函数,但[Edit](编辑)按钮传递的是系统ID,[Create](创建)按钮传递的是无效的系统ID。函数调用更新SelectedSystemID存储,然后使用该存储过滤Domains(域)表和模态的系统列表。
如果在加载页面时单击[Create],则模态会打开并显示占位符(因为selectedSystemID是-1,所以不是有效的系统)。如果单击[Edit]按钮,模态将打开并显示系统名称(因为它已从过滤器中找到正确的系统)。如果您现在再次单击[Create]按钮,尽管selectedSystemID是-1并且过滤函数返回未定义,模态输入字段仍然显示最后过滤的系统名称。我不完全明白为什么,并正在寻找两个解释为什么输入值没有重新评估,以及如何修复它。我想我需要一个useRef或useEffect,但不确定在哪里或如何。任何帮助都是非常感谢的。我已经用硬编码的JSON替换了API调用,这是一个精简版的响应。

import { use, useEffect, useState } from "react";
import { listSourceSystems } from "./api/SourceSystems/index";

export default function Sourcesystem() {
  const [systems, setSystems] = useState([]);
  const [selectedSystemID, setSelectedSystemID]  = useState(-1)
  const [modalIsOpen, setModalisOpen] = useState(false)

  async function fetchData() {
     const listSourceSystems = [
      {
          "id": 1,
          "systemName": "Order Management",
          "domains": [
              {
                  "id": 1,
                  "domainName": "Customer"
              },
              {
                  "id": 2,
                  "domainName": "Order"
              },
          ]
      },
      {
          "id": 2,
          "systemName": "Warehouse Managment",
          "domains": [
              {
                  "id": 9,
                  "domainName": "Product"
              }
          ]
      }
  ]
   // setSystems(await listSourceSystems());
    setSystems(listSourceSystems)
    console.log(systems)
  }

  useEffect(() => {
    fetchData();
  }, []);

  function filterDomains(systemID) {
    setSelectedSystemID(systemID)
  }

  function selectedSystem (){
    const ss = systems.filter(s=> s.id === selectedSystemID)[0]
    return ss
  }

  function openModal(systemID){
    filterDomains(systemID)
    setModalisOpen(true)
    console.log("openModal")
  }
  function closeModal(){
    setModalisOpen(false)
    console.log("closeModal")
  }

  return (
    <>
      <div className="flex flex-col mx-10 mt-4">
      <h1 className="text-3xl font-bold underline text-center">Source Systems</h1>
        <div className="divider"></div>
        <div className="grid h-50 card bg-base-300 rounded-box place-items-center">
          <table className="table table-compact w-full">
            <thead>
              <tr>
                <th className="font-bold px-5">Name</th>
                <th>actions</th>
              </tr>
            </thead>
            <tbody>
              {systems && systems.map((system) => (
                <tr 
                  key={system.id} 
                  className={`hover ${system.id === selectedSystemID? "active text-secondary font-bold": ""}`}
                  onClick={() => filterDomains(system.id)}
                >
                  <td className="px-5">{system.systemName}</td>
                  <td>
                    <button 
                      className="btn btn-primary btn-sm"
                      onClick={() => openModal(system.id)}
                    >
                      Edit
                    </button>
                  </td>
                </tr>
                ))}
            </tbody>
            <tfoot>
              <tr>
                <td colSpan="4" className="text-center font-bold accent">Add a new Source System</td>
                <td>
                  <button  
                    className="btn btn-primary btn-wide btn-sm"
                    onClick={()=> openModal(-1)}
                  >
                    click here
                  </button>
                </td>
              </tr>
            </tfoot>
          </table>
        </div>
        <div className="divider mt-0 before:bg-secondary after:bg-secondary"></div> 
        <div>
          <div className="grid h-20 card bg-primary-800 rounded-box place-items-center">
            <table className="table table-compact w-full table-fixed table-zebra">
              <thead>
                <tr>
                  <th className="text-left px-5">Domain</th>
                  <th className="text-right px-5">Source System</th>
                </tr>
              </thead>
              <tbody>
                { 
                  selectedSystem()?.domains.map(d => (
                    <tr key={d.id} className="hover">
                      <td className="px-5">{d.domainName}</td>
                      <td className="table-cell-2 text-right px-5">{systems.filter(s => s.id === selectedSystemID).systemName}</td>
                    </tr>
                  ))
                }
              </tbody>
            </table>
          </div>
        </div>
        {/* !-- Modal --> */}
        <input type="checkbox" id="source-system-modal" className=" modal-toggle" checked={modalIsOpen} />
        <div className="modal">
          <div className="modal-box">
            <h3>Source System Maintenance</h3>
            <form>
              <input 
                type="text" 
                placeholder="System Name placeholder"
                className="input input-bordered input-primary input-sm w-full"
                value={selectedSystem()?.systemName }
              >
              </input>
            </form>
            <div className="modal-action">
              <label htmlFor="source-system-modal" className="btn btn-info">Submit</label>
              <label htmlFor="source-system-modal" className="btn btn-warning btn-outline" onClick={()=> closeModal()}>Cancel</label>
            </div>
          </div>
        </div>
      </div>
    </>
  )}
s8vozzvw

s8vozzvw1#

再一次,当我把它放到Stack Overflow上时,它把我引向了一条不同的查询路径。原来原因很简单。输入中的值必须总是返回一个字符串,所以我需要做一个三元检查,如果函数返回undefined,实际上返回一个空字符串

value={selectedSystem()? selectedSystem().systemName : "" }

相关问题