簡體   English   中英

以表格形式提交時,我無法更新 state

[英]I can't update state when submitted in a form

我需要更新主頁上的 state,問題是我將值更新了 3 個級別...

該組件是我獲取所有城市的地方,通過城市將數據放在 State 和 map 上。

城市頁面.tsx

export const CitiesPage = () => {
  const [cities, setCities] = useState<City[]>([]);

  useEffect(() => {
    getCities().then(setCities);
  }, []);

  return (
    <>
      <PageTitle title="Cities" />
      <StyledCitySection>
        <div className="headings">
          <p>Name</p>
          <p>Iso Code</p>
          <p>Country</p>
          <span style={{ width: "50px" }}></span>
        </div>
        <div className="cities">
          {cities.map((city) => {
            return <CityCard key={city.id} city={city} />;
          })}
        </div>
      </StyledCitySection>
    </>
  );
};

在下一個組件中,我顯示城市和選項以顯示刪除和更新模式。

CityCard.tsx

export const CityCard = ({ city }: CityProps) => {
  const [showModal, setShowModal] = useState(false);

  const handleModal = () => {
    setShowModal(true);
  };

  const handleClose = () => {
    setShowModal(false);
  };

  return (
    <>
      {showModal && (
        <ModalPortal onClose={handleClose}>
          <EditCityForm city={city} closeModal={setShowModal} />
        </ModalPortal>
      )}
      <StyledCityCard>
        <p className="name">{city.name}</p>
        <p className="isoCode">{city.isoCode}</p>
        <p className="country">{city.country?.name}</p>
        <div className="options">
          <span className="edit">
            <FiEdit size={18} onClick={handleModal} />
          </span>
          <span className="delete">
            <AiOutlineDelete size={20} />
          </span>
        </div>
      </StyledCityCard>
    </>
  );
};

最后,向下三層,我有這個組件。

編輯城市表格.tsx

export const EditCityForm = ({ city, closeModal }: Props) => {
  const [updateCity, setUpdateCity] = useState<UpdateCity>({
    countryId: "",
    isoCode: "",
    name: "",
  });

  const handleChange = (
    evt: ChangeEvent<HTMLInputElement | HTMLSelectElement>
  ) => {
    const { target } = evt;
    setUpdateCity({ ...updateCity, [target.name]: target.value });
  };

  const handleSubmit = (evt: FormEvent<HTMLFormElement>) => {
    evt.preventDefault();
    const { id: cityId } = city;
    updateCityHelper(cityId, updateCity);
    closeModal(false);
  };

  useEffect(() => {
    setUpdateCity({
      isoCode: city.isoCode,
      name: city.name,
      countryId: city.country?.id,
    });
  }, [city]);

  return (
    <form onSubmit={handleSubmit}>
      <Input
        label="Iso Code"
        type="text"
        placeholder="Type a IsoCode..."
        onChange={handleChange}
        name="isoCode"
        value={updateCity.isoCode}
      />
      <Input
        label="Name"
        type="text"
        placeholder="Paste a Name.."
        onChange={handleChange}
        name="name"
        value={updateCity.name}
      />
      <CountrySelect
        label="Country"
        onChange={handleChange}
        value={city.country?.name || ""}
        name="countryId"
      />
      <Button type="submit" color="green" text="Update" />
    </form>
  );
};

編輯表單,檢索從CityCard.tsx傳遞的數據並更新 State,將數據傳遞到更新信息的 function,關閉模式和...這是我不知道該做什么的地方。

當我在EditCityForm.tsx上提交時,如何顯示在CitiesPage.tsx上更新的信息

任何幫助將不勝感激。
謝謝!

只要您有嵌套結構並希望在整個應用程序中訪問數據,我建議您使用 React-Redux 或 Context API。

但是在這種情況下,您可以將setCitiescities作為道具傳遞給CityCard ,然后在EditCityForm組件中傳遞相同的道具,您可以在 handleSubmit 中執行類似的操作。

const handleSubmit = (evt: FormEvent<HTMLFormElement>) => {
    evt.preventDefault();
    let updatedCities = [...cities];
    updatedCities.forEach(el => {
       if(el.id == updateCity.id) {
         el.countryCode = updateCity.countryCode;
         el.name = updateCity.name;
         el.isoCode = updateCity.isoCode;
       }
    })
    setCities(updatedCities);
    closeModal(false);
  };

您將更新后的值存儲在不同的 state 中,即updateCity state,但您應該做的是更新原始cities state。雖然這兩個狀態不相關,但同時您的 UI 取決於cities狀態的數據,所以如果你想更新 UI,你需要做的是使用它的 setter function setCities更新cities的 state 。

就像傳遞 state 一樣,你也傳遞它的 setter,並使用 setter function 來更新狀態值:

// CitiesPage
{cities.map((city) => {
    return <CityCard key={city.id} city={city} setCities={setCities} />;
})}

// CityCard
export const CityCard = ({ city, setCities }: CityProps) => {
    // ...

    return (
        // ...
        <ModalPortal onClose={handleClose}>
          <EditCityForm city={city} closeModal={setShowModal} setCities={setCities} />
        </ModalPortal>
        // ...
    )
}


// EditCityForm
export const EditCityForm = ({ city, closeModal, setCities }: Props) => {
  // const [updateCity, setUpdateCity] = useState<UpdateCity>({  // no need for this
  //   countryId: "",
  //   isoCode: "",
  //   name: "",
  // });  

  const handleSubmit = (evt: FormEvent<HTMLFormElement>) => {
    evt.preventDefault();
    const { id: cityId } = city;
    setCities(); // your update logic
    closeModal(false);
  };
}

暫無
暫無

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

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