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

Posted

技术标签:

【中文标题】如何在不刷新整个页面的情况下重新加载组件?【英文标题】:How to reload a component without refreshing the entire page? 【发布时间】:2020-11-14 08:14:10 【问题描述】:

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

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

当前如何使用 refreshPage 函数重新加载。 谢谢!

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;

【问题讨论】:

更新了我的答案,如果有帮助,请包含一个示例。 【参考方案1】:

如果报价是在不刷新整个页面的情况下显示新报价,则将axios请求从钩子中去掉,放到自己的函数中。

  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 进行加载,但这应该是一个好的开始。

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

这里还有一个示例代码,看看它是如何工作的。 点击Run code sn-p查看它的工作情况。

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/axios@0.19.2/dist/axios.min.js"></script>

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

【讨论】:

感谢codingwithmanny,刚刚测试了它,它可以工作!【参考方案2】:

Codingwithmanny 打败了我。

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

Quote.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;

代码沙盒:https://codesandbox.io/s/quote-generator-heufm

【讨论】:

【参考方案3】:

您应该在单击按钮时调用 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;

你的 Qoute 组件:

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;

【讨论】:

【参考方案4】:

你可以这样做。

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

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

这是您升级后的沙盒 -> link

引用.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>
  );
;

【讨论】:

以上是关于如何在不刷新整个页面的情况下重新加载组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不刷新整个页面的情况下让 Grunt/Watch/LiveReload 重新加载 Sass/CSS?

如何在不刷新页面的情况下在 ReactJS 中重新加载?

如何在不刷新页面的情况下重新加载数据表?

如何在不重新加载页面的情况下刷新 div 和 mysql 代码

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

如何在不重新加载 HTML 页面的情况下重定向锚标记链接?