【问题标题】:Components re-render whenever I type something but I want re-render only after onClick of button每当我输入内容时组件都会重新渲染,但我只想在按钮的 onClick 之后重新渲染
【发布时间】:2021-10-16 16:04:06
【问题描述】:

目前,我正在开发一个 REACT 应用程序,它采用两个名称,给出一个百分比,然后根据该百分比显示一首诗。第一个提交收集信息并显示预期内容(百分比和诗歌)。不过在那之后,一旦我开始在输入字段中输入内容,LovePercentContent 和 LovePoem 就会继续重新渲染。注意:正在渲染的诗歌是从数组中随机挑选的。所以最大的问题是当你在输入字段中输入时,这首诗会不断更新。我对 React 还是很陌生,并通读了句柄事件文档。但我似乎仍然有问题。

https://reactjs.org/docs/handling-events.html

以下是我目前尝试过的。

应用程序的实时版本 https://love-poem-calculator.netlify.app/

import React, { useState } from "react";
import LovePercentContent from "../LovePercentContent/LovePercentContent";
import LovePoem from "../LovePoem/LovePoem";

const LovePercent = () => {
    const [yourName, setYourName] = useState("");
    const [yourCrushName, setYourCrushName] = useState("");
    const [yourLovePercent, setYourLovePercent] = useState("");
    const [yourLovePoems, setYourLovePoems] = useState("");
    const [yourSwitch, setYourSwitch] = useState(false);
    const [yourNameMissing, setYourNameMissing] = useState("");

    const handleSubmit = (e) => {
        e.preventDefault();
        if (yourName !== "" && yourCrushName !== "") {
            let calcQueryURL =
                "https://love-calculator.p.rapidapi.com/getPercentage?fname=" +
                yourName +
                "&sname=" +
                yourCrushName;
            console.log("yourName2", yourName);
            getLovePercent(calcQueryURL);
            setYourName("");
            setYourCrushName("");
        } else {
            console.log("you most enter two names");
            setYourNameMissing("please enter both names");
        }
    };

    const getLovePercent = (url) => {
        fetch(url, {
            method: "GET",
            headers: {
                "x-rapidapi-key": process.env.REACT_APP_PERCENT_API_KEY,
                "x-rapidapi-host": "love-calculator.p.rapidapi.com",
            },
        })
            .then((response) => response.json())
            .then((data) => {
                poemLines(data);
                return setYourLovePercent(data);
            })
            .catch((err) => {
                console.error(err);
            });
    };

    function poemLines(data) {
        let percent = data.percentage;
        let url = `https://poetrydb.org/linecount/${percent}`;
        fetch(url, {
            method: "GET",
        })
            .then((response) => response.json())
            .then((data) => {
                return setYourLovePoems(data);
            })
            .then(() => {
                return setYourSwitch(true);
            })
            .catch((err) => {
                console.error(err);
            });
    }

    if (yourSwitch) {
        return (
            <>
                <h2>Enter Two Names:</h2>
                <input
                    name="yourName"
                    value={yourName}
                    placeholder="Your Name"
                    onChange={(e) => setYourName(e.target.value)}
                />
                <input
                    name="yourCrushName"
                    value={yourCrushName}
                    placeholder="Your Crush's Name"
                    onChange={(e) => setYourCrushName(e.target.value)}
                />
                <button type="submit" className="btn" onClick={handleSubmit}>
                    Get Poem
                </button>
                <LovePercentContent data={yourLovePercent} />
                <LovePoem data={yourLovePoems} />
            </>
        );
    }

    return (
        <>
            <h2>Enter Two Names:</h2>
            <input
                name="yourName"
                value={yourName}
                placeholder="Your Name"
                onChange={(e) => setYourName(e.target.value)}
            />
            <input
                name="yourName"
                value={yourCrushName}
                placeholder="Your Crush's Name"
                onChange={(e) => setYourCrushName(e.target.value)}
            />
            <button type="submit" className="btn" onClick={handleSubmit}>
                Get Poem
            </button>
            {yourNameMissing}
        </>
    );
};

export default LovePercent;

【问题讨论】:

  • 加载一段时间后出现什么错误?
  • @SulemanAhmad 我没有收到错误消息。每次我在输入字段中输入时,这首诗都会不断重新渲染。我已经用更多信息更新了我原来的帖子。
  • 因此您只想在单击按钮时获取诗歌。对吗?
  • @SulemanAhmad 这正是我想要的。注意:感谢标题建议。

标签: javascript reactjs react-hooks components single-page-application


【解决方案1】:

你可以创建一个布尔状态

const [dataBool, setDataBool]=useState(false);

并在您单击按钮时通过创建函数或根据需要设置此true。之后在屏幕上显示poem data 时添加条件。如果这个布尔值为真,则返回诗歌,否则不返回。像这样:

   e.g. {dataBool ? showPoems : notShowPoems}

这样它只会在你点击它时显示。

【讨论】:

    【解决方案2】:

    我会说 Reactjs 的行为是正常的,你不应该太担心它


    • 你所说的reloading实际上是re-rendering

    • 每次状态变化(yourNameyourCrushName 在您的情况下)都会导致 Reactjs 重新渲染整个组件。

    完全没问题,实际上 Reactjs 就是这样工作的

    重渲染还不错,只有更新DOM是很有价值的,重渲染并不意味着DOM更新了,因为Reactjs应用了Virtual Dom机制

    如果您不希望您的组件重新渲染,请考虑改用ref

    【讨论】:

    • 感谢您的快速回复。唯一的问题是正在渲染的诗歌是从数组中随机挑选的。所以最大的问题是当你在输入字段中输入时,这首诗会不断更新。我会试试红色,看看情况如何。注意:我更新了我的帖子以添加到诗歌数组部分。
    猜你喜欢
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 2019-06-01
    • 2020-02-18
    • 2018-07-05
    • 2018-08-12
    • 2020-05-21
    • 2020-01-18
    相关资源
    最近更新 更多