Kur bëhet fjalë për React, koncepti i fluksit të anasjelltë të të dhënave është ajo që me të vërtetë mbyll lakin kur mendoni në React! Ne mund t'i japim komponentët me mbështetëse dhe gjendje që rrjedhin poshtë një hierarkie të komponentëve, por çfarë ndodh me anasjelltas? Për shembull, kur një hyrje e përdoruesit po ndryshon gjendjen diku më poshtë në hierarki, si do të rrjedhin ato të dhëna më pas, në drejtim të kundërt? Ndërsa zhytemi në përgjigjet për këto pyetje, le të japim një shembull, veçanërisht nëse një përdorues po përpiqet të shtojë një birrë të re në një faqe interneti që përmban informacione për birrën!

Së pari, le të shohim pemën e hierarkisë së komponentëve!

Le të supozojmë se:

  • Ekziston një gjendje në Header që mban informacion nga një API
function Header() {
  const [beerList, setBeerList] = useState([]);

  useEffect(() => {
    fetch("http://localhost:6001/beers")
      .then((res) => res.json())
      .then(setBeerList);
  }, []);
  • Kjo gjendje më pas kalon te komponenti BeerContainer, ku më pas manipulohet dhe kthen komponentët e BeerCard.
function Header() {
  const [beerList, setBeerList] = useState([]);

  useEffect(() => {
    fetch("http://localhost:6001/beers")
      .then((res) => res.json())
      .then(setBeerList);
  }, []);

  return (
    <div>
      <NavBar />
      <Switch>
        <Route path="/beers">
          <BeerContainer beerList={beerList} />
        </Route>
        <Route path="/form">
          <Form />
        </Route>
        <Route path="/">
          <Home />
        </Route>
      </Switch>
    </div>
  );
}

function BeerContainer({ beerList, updateSearch }) {
  const beerCards = beerList.map((beer) => (
    <BeerCard
      key={beer.id}
      name={beer.name}
      tagline={beer.tagline}
      image={beer.image_url}
      description={beer.description}
      contribute={beer.contributed_by}
    />
  ));

  return (
    <div>
      <Search />
      <div>
        {beerCards}
      </div>
    </div>
  );
}
  • Komponenti Form ka gjendje të shumta dhe në kthimin e këtij komponenti, jeton një element i formës me hyrje.
  • Çdo hyrje, më pas ka një veti onChange që mban një funksion anonim që thërret çdo funksion vendosës për çdo gjendje.
function Form() {
  const [name, setName] = useState("");
  const [tagline, setTagLine] = useState("");
  const [image, setImage] = useState("");
  const [description, setDescription] = useState("");
  const [contributer, setContributer] = useState("");
  let history = useHistory();

  const handleSubmit = (e) => {
    e.preventDefault();
    let newBeerObj = {
      name: name,
      tagline: tagline,
      image_url: image,
      description: description,
      contributer: contributer,
    };
    fetch("http://localhost:6001/beers", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(newBeerObj),
    })
      .then((r) => r.json())
      .then();
    e.target.reset();
    history.push("/beers");
  };
  return (
    <div>
      <form onSubmit={handleSubmit}>
        <div>
          <label>
            Enter Name of Beer:
          </label>
          <input
            type="text"
            id="name"
            name="name"
            onChange={(e) => setName(e.target.value)}
            placeholder="Name of Beer"
          />
        </div>
        <div>
          <label>
            Enter Tagline:
          </label>
          <input
            type="text"
            id="tagline"
            name="tagline"
            onChange={(e) => setTagLine(e.target.value)}
            placeholder="Tagline"
          />
        </div>
        <div>
          <label>
            Enter Image:
          </label>
          <input
            type="text"
            id="image"
            name="image"
            onChange={(e) => setImage(e.target.value)}
            placeholder="Image URL"
          />
        </div>
        <div>
          <label>
            Enter Description of Beer:
          </label>
          <textarea
            type="text"
            id="description"
            name="description"
            onChange={(e) => setDescription(e.target.value)}
            placeholder="Description"
          />
        </div>
        <div>
          <label>
            Enter Name of Contributor:
          </label>
          <input
            type="text"
            id="contributer"
            name="contributer"
            onChange={(e) => setContributer(e.target.value)}
            placeholder="Contributor"
          />
        </div>
        <div>
          <button>
            Submit
          </button>
        </div>
      </form>
    </div>
  );
}

Aktualisht shikojmë të dy komponentët Header dhe Form:

  1. Aktualisht nuk ka asgjë që kalohet nga Header në Form, si dhe Forma që nuk pranon asgjë nga Header.
  2. VETËMlidhja pseudo që ka Forma dhe Header është se Formulari ka një kërkesë POST e cila po trajtohet nga funksioni handleSubmit.
  3. Në fund të fundit, kur përdoruesi dorëzon informacionin, pjesa e pasme aktualisht po përditësohet, por pjesa e përparme jo. Që përdoruesi të shohë birrën e tij që ka dorëzuar, përdoruesi më pas do të duhet të rifreskojë faqen, gjë që shkakton një kërkesë tjetër GET në Header.

Pra, pse po ndodh kjo? Mos harroni se të vetmet rastet që një komponent do të riprodhojë në React, janë vendosur shumë bukur në këtë postimin e StackOverflow:

- Komponenti merr rekuizita të reja

- Gjendja është përditësuar

- Vlera e kontekstit përditësohet (nëse komponenti dëgjon ndryshimin e kontekstit duke përdorur useContext)

- Komponenti prind ri-rikthehet për shkak të ndonjë prej arsyeve të mësipërme

Asnjë nga këto kushte nuk po ndodh në titullin tonë të komponentit kryesor, kështu që si ta bëjmë këtë të ndodhë? Në React dhe përmes rekuizitave, si mund të hyjë Header në informacionin në Form, ose si mundet Form t'ia kalojë atë informacion Header-it pa manipulim në fund?

Përgjigja është duke pasur një funksion TË PËRKUFIZUARPRINDOR (Titulli), por më pas INVOKEDFËMIJË ( Forma).

Pra, së pari, le të përcaktojmë një funksion addBeerState në Header që do të marrë një parametër dhe do të përditësojë gjendjen me atë parametër. Pastaj kaloni funksionin si mbështetës në Form.

Më pas, ne e pranojmë atë mbështetje në Form, dhe më pas do ta thërrasim në mënyrë pesimiste këtë funksion pas kërkesës POST.

Tani, kur një përdorues dorëzon një birrë të re, pjesa e përparme duhet gjithashtu të përditësohet sepse kushtet e ri-renderimit në React tani janë duke u plotësuar! Kjo është e gjitha për shkak të funksionit në Header, i cili kalon si një mbështetje në Form, i cili më pas po përditëson gjendjen, në Header, me të dhënat nga hyrjet e formularit.

Duke ndjekur logjikën e një funksioni të përcaktuar në prind dhe të thirrur në fëmijë, ju gjithashtu mund t'i kaloni të dhënat e hyrjes së përdoruesit nga komponenti i kërkimit, deri në Header! Thjesht duhet të siguroheni që të kaloni dhe të pranoni mbështetëse nëpër pemë! (Nuk mund të kapërcehen komponentët)

Nëse, keni arritur deri këtu, faleminderit që lexoni! Shpresojmë që kjo të dha një kuptim më të mirë të rrjedhës së të dhënave të anasjellta dhe pse është koncepti thelbësor mbyllja e ciklit të të menduarit të React!