任何帮助将不胜感激,我已经在 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;
如果报价是要显示新的报价而不刷新整个页面,就把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>
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
您应该在单击按钮时调用 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;
你可以做这样的事情。
在
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>
);
};
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 上。