Çözüldü: Girdi yazılamıyor — React

Mar 09 2023
Selam Dünya! React'te formlarla çalışırken, value özelliği ayarlanmışsa giriş alanına/metin kutusuna yazamayacağımız bir sorunla karşılaşabiliriz. Asıl sorunun ne olduğunu ve nasıl çözdüğümü gösterecektim.

Selam Dünya!

valueReact'te formlarla çalışırken, özellik ayarlanmışsa giriş alanına/metin kutusuna yazamayacağımız bir sorunla karşılaşabiliriz . Asıl sorunun ne olduğunu ve nasıl çözdüğümü gösterecektim.

Senaryo

Gereklilik

API gövdesinde iletilmesi gereken E-posta, Ad ve Mesaj olmak üzere üç alan gerektiren bir API'm var. Kullanıcı arabiriminde, bu değerleri bir giriş alanında veya metin alanında alıyor ve API çağrısını tetiklemek için bir düğme kullanıyor olacaktık.

API'de beklenen yapı şuna benzer:

{
"email": "[email protected]",
"name": "Test",
"message": "Hi, this is a test message."
}

nameReact uygulamasında, ve almak için 2 giriş alanı email, almak için bir metin alanı messageve API çağrısını tetiklemek ve 3 değeri göndermek için bir düğme içeren bir bileşen oluşturdum . Bileşen böyle görünüyordu:

import { useState } from "react";
import callApi from "../axios/axios";
import "./contact.scss";
const Contact = () => {
  const payloadInitial = {
    sender: "",
    email: "",
    message: "",
  };
  const initialClass = "form-input";
  const [payload, setPayload] = useState(payloadInitial);
  // Captures Sender name
  const setName = (name) => {
    const temp = payload
    temp.sender = name
    setPayload(temp)
  };
  // Captures Email
  const setEmail = (email) => {
    const temp = payload
    temp.email = email
    setPayload(temp)
  };
  // Captures Message
  const setMessage = (message) => {
    const temp = payload
    temp.message = message
    setPayload(temp)
    checkCanSend();
  };
  // Triggers API call on button click
  const sendMessage = (evt) => {
    evt.preventDefault();
    callApi
      .post("/email", payload)
      .then((res) => {
        console.log("Response: ", res)
      })
      .catch((err) => {
        console.error("Something went wrong: ", err)
      });
  };
  return (
    <div className="form-container">
      <h2 className="form-title">Write to me</h2>
      <div className="form-container">
        <!--Input to get sender name-->
        <label>Your Name</label>
        <input
          type={"text"}
          aria-label="Your Name"
          value={payload.sender}
          onChange={(e) => setName(e.target.value)}
        ></input>
        <!--Input to get sender email-->
        <label>Your Email</label>
        <input
          type={"email"}
          aria-label="Your Email"
          value={payload.email}
          onChange={(e) => setEmail(e.target.value)}
        ></input>
        <!--Textbox to get the message-->
        <label>Type in your message</label>
        <textarea
          rows={8}
          value={payload.message}
          onChange={(e) => setMessage(e.target.value)}
        ></textarea>
        <!--Button to trigger API call-->
        <button onClick={(e) => sendMessage(e)} className="send-button">
          Send Message
        </button>
      </div>
    </div>
  );
};

export default Contact;

Sorun

Yukarıdaki kod, birden fazla karakter yazamadığım bir soruna neden oluyordu.

Çözüm

Sorunun çözümü ise şu: onClick fonksiyonunda durumu bir temp değişkeninde depolamak yerine temp içindeki değeri değiştirip temp'i state'e ayarlamak yerine direkt olarak state güncellemesi yapmalıyız .

Bizim durumumuzda, işlevi ele alalım setName. İşlev şu şekilde değiştirilmelidir:

const setName = (name) => {
    setPayload((prev) => ({
      ...prev,
      sender: name,
    }));
    checkCanSend();
  }

Şimdi giriş alanına yazabiliriz.

Nihai kod şöyle olacaktır:

import { useState } from "react";
import callApi from "../axios/axios";
import "./contact.scss";
const Contact = () => {
  const initialClass = "form-input";
  const [payload, setPayload] = useState(payloadInitial);
  // Captures Sender name
  const setName = (name) => {
    setPayload((prev) => ({
      ...prev,
      sender: name,
    }));
    checkCanSend();
  };
  // Captures Email
  const setEmail = (email) => {
    setPayload((prev) => ({
      ...prev,
      email,
    }));
    checkCanSend();
  };
  // Captures Message
  const setMessage = (message) => {
    setPayload((prev) => ({
      ...prev,
      message,
    }));
    checkCanSend();
  };
  // Triggers API call on button click
  const sendMessage = (evt) => {
    evt.preventDefault();
    callApi
      .post("/email", payload)
      .then((res) => {
        console.log("Response: ", res)
      })
      .catch((err) => {
        console.error("Something went wrong: ", err)
      });
  };
  return (
    <div className="form-container">
      <h2 className="form-title">Write to me</h2>
      <div className="form-container">
        <!--Input to get sender name-->
        <label>Your Name</label>
        <input
          type={"text"}
          aria-label="Your Name"
          value={payload.sender}
          onChange={(e) => setName(e.target.value)}
        ></input>
        <!--Input to get sender email-->
        <label>Your Email</label>
        <input
          type={"email"}
          aria-label="Your Email"
          value={payload.email}
          onChange={(e) => setEmail(e.target.value)}
        ></input>
        <!--Textbox to get the message-->
        <label>Type in your message</label>
        <textarea
          rows={8}
          value={payload.message}
          onChange={(e) => setMessage(e.target.value)}
        ></textarea>
        <!--Button to trigger API call-->
        <button onSubmit={(e) => sendMessage(e)} className="send-button">
          Send Message
        </button>
      </div>
    </div>
  );
};

export default Contact;

İlk olarak https://sriram23.hashnode.dev adresinde yayınlanmıştır .