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

How to reload a component without refreshing the entire page?

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

项目 link: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;

如果引用是为了显示新的引用而不刷新整个页面,将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 用于加载,但这应该是一个好的开始。

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

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

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 先于我。

将 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;

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

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

你可以这样做。

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

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

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

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