如何在不刷新整个页面的情况下重新加载组件?

问题描述 投票:0回答:5

任何帮助将不胜感激,我已经在 React 中构建了一个简单的报价生成器项目,并且希望在不渲染整个页面的情况下加载新报价。目前,我使用钩子并且引号状态驻留在一个组件中,是否可以使用单击处理程序从另一个组件重新加载/刷新状态?

项目链接:https://codesandbox.io/s/quote-generator-czffn?file=/src/components/buttons/Buttons.js

当前如何使用刷新页面函数重新加载。 谢谢!

import React from 'react';

const Buttons = ({ quotes, getNewQuote }) => {
  const twitterUrl = `https://twitter.com/intent/tweet?text=${quotes.joke}`;
  //   console.log(twitterUrl);

  function refreshPage() {
    window.location.reload(false);
  }

  return (
    <div className='button-container'>
      <button
        onClick={() => window.open(twitterUrl, '_blank')}
        className='twitter-button'
        id='twitter'
        tittle='Tweet This!'
      >
        <i className='fab fa-twitter'></i>
      </button>
      <button id='new-quote' onClick={refreshPage}>
        New Quote
      </button>
    </div>
  );
};

export default Buttons;
javascript reactjs axios react-hooks react-component
5个回答
4
投票

如果报价是要显示新的报价而不刷新整个页面,就把axios请求从hook中去掉,放到自己的函数中。

  const getQuotes = () => {
    axios
      .get("https://geek-jokes.sameerkumar.website/api?format=json")
      .then(res => {
        setQuotes(res.data);
        // console.log(res.data);
      })
      .catch(err => console.log(err));
  }

// ...

<Buttons onClick={getQuotes} quotes={quotes} />

然后调整按钮以在单击时使用此功能:

const Buttons = ({ quotes, getNewQuote, onClick }) => {

// ...

<button id="new-quote" onClick={onClick}>
  New Quote
</button>

您可能想在检索内容时添加动画以及用于加载的

useState
,但这应该是一个好的开始。

=======更新=======

这里还有一个示例代码,可以了解它是如何工作的。 单击 运行代码片段 以查看其工作情况。

const { useState, useEffect } = React;

const Quote = props => {
  return <section>
    <blockquote>
      {JSON.stringify(props.quote)}
    </blockquote>
    <button onClick={props.onClick}>Get Quote</button>
  </section>
}

const App = () => {
  const [quotes, setQuotes] = useState(null);
  const [loading, setLoading] = useState(true);
  
  const getQuotes = () => {
    setLoading(true);
    axios
      .get("https://geek-jokes.sameerkumar.website/api?format=json")
      .then(res => {
        if (res.data && res.data.joke) {
          setQuotes(res.data.joke);
        }
        setLoading(false);
      })
      .catch(err => {
        console.log(err);
        setLoading(false);
      });
  }
  
  useEffect(() => {
    getQuotes();
  }, []);

  return loading ? <p>Loading...</p> : <Quote quote={quotes} onClick={getQuotes} />
}


ReactDOM.render(<App />, document.querySelector('#root'));
body {
  background: #efefef;
  font-family: Arial, sans-serif;
  padding: 20px;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

section {
   background: white;
   border-radius: 6px;
   display: block;
   padding: 10px;
}

blockquote {
  padding: 10px;
  margin: 0 0 10px 0; 
  border-bottom: 1px solid #efefef;
  font-size: 21px;
}

button {
border-radius: 4px;
background: blue;
color: white;
border: none;
height: 40px;
padding: 0 12px;
font-size: 14px;
}

p {
  display: block;
  max-width: 80px;
  background: white;
  border-radius: 6px;
  padding: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>

<div id="root"></div>


0
投票

Codingwithmanny 比我先一步。

将 axios 调用放入其自己的函数中,并将该函数传递给按钮组件。

引用.js:

import React, { useState, useEffect } from "react";
import Buttons from "../buttons/Buttons";
import axios from "axios";

const Quote = () => {
  const [quotes, setQuotes] = useState("");

  const fetchQuotes = () => {
    axios
      .get("https://geek-jokes.sameerkumar.website/api?format=json")
      .then(res => {
        setQuotes(res.data);
        // console.log(res.data);
      })
      .catch(err => console.log(err));
  };
  useEffect(() => {
    console.log("new quote requested");
  }, [quotes]);

  return (
    <div className="quote-text">
      <i className="fas fa-quote-left" />
      <span id="quote"> {quotes.joke}</span>
      <Buttons quotes={quotes} getNewQuote={fetchQuotes} />
    </div>
  );
};

export default Quote;

Buttons.js

import React from "react";

const Buttons = ({ quotes, getNewQuote }) => {
  const twitterUrl = `https://twitter.com/intent/tweet?text=${quotes.joke}`;
  //   console.log(twitterUrl);

  return (
    <div className="button-container">
      <button
        onClick={() => window.open(twitterUrl, "_blank")}
        className="twitter-button"
        id="twitter"
        tittle="Tweet This!"
      >
        <i className="fab fa-twitter" />
      </button>
      <button id="new-quote" onClick={getNewQuote}>
        New Quote
      </button>
    </div>
  );
};

export default Buttons;

Codesandbox:https://codesandbox.io/s/quote-generator-heufm


0
投票

您应该在单击按钮时调用 New Qoute API。

您按钮组件

import React from "react";

const Buttons = ({ quotes, getNewQuote }) => {
  const twitterUrl = `https://twitter.com/intent/tweet?text=${quotes.joke}`;
  //   console.log(twitterUrl);

  return (
    <div className="button-container">
      <button
        onClick={() => window.open(twitterUrl, "_blank")}
        className="twitter-button"
        id="twitter"
        tittle="Tweet This!"
      >
        <i className="fab fa-twitter" />
      </button>
      <button id="new-quote" onClick={getNewQuote}>
        New Quote
      </button>
    </div>
  );
};

export default Buttons;

您的报价组件:

import React, { useState, useEffect } from "react";
import Buttons from "../buttons/Buttons";
import axios from "axios";

const Quote = () => {
  const [quotes, setQuotes] = useState("");
  useEffect(() => {
    axios
      .get("https://geek-jokes.sameerkumar.website/api?format=json")
      .then(res => {
        setQuotes(res.data);
        // console.log(res.data);
      })
      .catch(err => console.log(err));
  }, []);

  const getNewQuote = () => {
    axios
      .get("https://geek-jokes.sameerkumar.website/api?format=json")
      .then(res => {
        setQuotes(res.data);
        // console.log(res.data);
      })
      .catch(err => console.log(err));
  }

  return (
    <div className="quote-text">
      <i className="fas fa-quote-left" />
      <span id="quote"> {quotes.joke}</span>
      <Buttons quotes={quotes} getNewQuote={getNewQuote}/>
    </div>
  );
};

export default Quote;

0
投票

你可以做这样的事情。

Quote.js
中创建
getNewQuote
函数并在
useEffect
中调用该函数。

然后,将

getNewQuote
函数传递给
Button
组件,并在
New Quote
按钮
onClick
设置
getNewQuote

这是您升级后的沙箱 -> 链接

报价.js

const Quote = () => {
  const [quotes, setQuotes] = useState("");
  useEffect(() => {
    getNewQuote();
  }, []);

  const getNewQuote = () => {
    axios
      .get("https://geek-jokes.sameerkumar.website/api?format=json")
      .then(res => {
        setQuotes(res.data);
        // console.log(res.data);
      })
      .catch(err => console.log(err));
  };

  return (
    <div className="quote-text">
      <i className="fas fa-quote-left" />
      <span id="quote"> {quotes.joke}</span>
      <Buttons getNewQuote={getNewQuote} quotes={quotes} /> // here you pass the getNewQuote function to the Buttons component
    </div>
  );
};

Buttons.js

const Buttons = ({ quotes, getNewQuote }) => {
  const twitterUrl = `https://twitter.com/intent/tweet?text=${quotes.joke}`;
  //   console.log(twitterUrl);

  return (
    <div className="button-container">
      <button
        onClick={() => window.open(twitterUrl, "_blank")}
        className="twitter-button"
        id="twitter"
        tittle="Tweet This!"
      >
        <i className="fab fa-twitter" />
      </button>
      <button id="new-quote" onClick={getNewQuote}> // here onClick you call the getNewQuote function
        New Quote
      </button>
    </div>
  );
};

0
投票

React 向元素提供 key 属性传递。我们可以使用关键属性通过硬刷新来重新加载 React 环境中的页面,这对于 React 生态系统来说是有点奇怪的做法。因此,每当 key 属性发生变化时,react diffing 算法就会出现在中间,然后它首先在 key 更改时卸载前一个组件,然后再次在 DOM 上加载该组件,请不要将其与 reload 混淆,它首先作为 key 渲染孩子们的改变。

示例: 我让用户登录到该网站,并且可以更新令牌(使用其他一些用户配置文件),即使用户仍然登录。

代码:

import React, { useEffect, useState, Fragment } from "react";
import axios from "axios";

const TokenComponent = ({ children }) => {
  const [token, setToken] = useState(null);

  const fetchToken = async () => {
    try {
      const response = await axios.get("/api/token"); 
      const fetchedToken = response.data.token; 
      setToken(fetchedToken);
    } catch (error) {
      console.error("Error fetching token:", error);
    }
  };

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

  if (!token) {
    return <p>Loading token...</p>; 
  }

  return <Fragment key={token}>{children}</Fragment>;
};

export default TokenComponent;

现在您可以看到,每当令牌更新时,反应都无法在节点中找到与前一个密钥(令牌)关联的组件,因此与前一个密钥关联的组件将首先卸载,并且将加载具有更新密钥的组件(不要混合)这需要重新加载)在 DOM 上。

© www.soinside.com 2019 - 2024. All rights reserved.