简体   繁体   English

如何通过单击组件外部的按钮来刷新 React 组件?

[英]How do I refresh a react component by clicking on a button outside the component?

I'm new to web development and decided to learn ReactJs. I am trying to create a random quote generator as a part of freecodecamp's frontend libraries project.我是 web 开发的新手,决定学习 ReactJs。我正在尝试创建一个随机报价生成器作为 freecodecamp 前端库项目的一部分。 Problem: I have a react component that fetches the quotes from a website and then displays a random quote on the screen.问题:我有一个反应组件,它从网站获取报价,然后在屏幕上显示随机报价。 I also have a button outside of the component whose sole purpose is to get a new code and display it onscreen.我在组件外部还有一个按钮,其唯一目的是获取新代码并将其显示在屏幕上。 How do I refresh the react component whenever I click the button?单击按钮时如何刷新反应组件? Any help is appreciated::D Here's my component:感谢任何帮助::D 这是我的组件:

 class MyComponent extends React.Component { constructor(props) { super(props); this.state = { quote: '' }; } componentDidMount() { fetch("https://type.fit/api/quotes").then(res => res.json()).then( (result) => { this.setState({ quote: result[Math.floor(Math.random() * result.length)] }); }, ) } render() { return ( <p id = 'reactQuote'>{this.state.quote.text}< /p> ); } } ReactDOM.render( MyComponent />, document.getElementById('text'))
 <div id="text"></div> <button id='new-quote'>New Quote</button>

create a component that would incapsulate both the button and your component, have the quote as state in the upper component and pass it down as props to your component, now when you press the button it will change the state in the upper component and it will be passed down to your component forcing it to refresh and display the new quote.创建一个组件来封装按钮和您的组件,在上部组件中引用 state 并将其作为道具传递给您的组件,现在当您按下按钮时,它将更改上部组件中的 state 并且它将传递给您的组件,迫使它刷新并显示新报价。

You can call a function on your button whenever you click on it.每当您单击按钮时,您都可以在按钮上拨打 function。 That function can be passed down to your button component as a prop. function 可以作为道具传递给您的按钮组件。

function fetchData(){
     fetch("https://type.fit/api/quotes")
        .then(res => res.json())
        .then(
          (result) => {
            this.setState({
              quote: result[Math.floor(Math.random() * result.length)]
          });
        },
      )
}

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

The component will automatically refresh when its state changes but the button and the text should be part of the component itself (or children of the component).该组件将在其 state 更改时自动刷新,但按钮和文本应该是组件本身的一部分(或组件的子组件)。 An example (using a single component) would be:一个示例(使用单个组件)是:

 // your component class RandomQuoteMachine extends React.Component { constructor() { super(); this.state = { quotes: [], // here you store an array of quote objects currentQuote: null // here you store the quote object that is currently displayed }; this.getRandomQuote = this.getRandomQuote.bind(this) } // when the component mounts, fetch the quotes from the API componentDidMount() { fetch("https://type.fit/api/quotes") // fetch the entire list of quotes from the API.then(response => response.json()) // turn the response into a Javascript object.then(result => { // update the state this.setState({ quotes: result, currentQuote: result[Math.floor(Math.random() * result.length)] || null }); }); } getRandomQuote() { // randomly select a quote from the state const newQuote = this.state.quotes[Math.floor(Math.random() * this.state.quotes.length)] || null; // update the state with the new current quote this.setState({ currentQuote: newQuote }); } render() { return ( <div> <blockquote>{ this.state.currentQuote && this.state.currentQuote.text || '' }</blockquote> <p className = "author">{ this.state.currentQuote && this.state.currentQuote.author || 'unknown' }</p> <button onClick = { () => this.getRandomQuote() }>get a new quote from the list</button> </div> ); } } // mounting the component in the page ReactDOM.render( < RandomQuoteMachine / >, document.getElementById('app'))
 /* A bit of styling, just for presentation sake */ * { font-family: sans-serif; } blockquote { font-size: 2rem; font-style: italic; margin: 0; padding: 0.5rem 0.5rem 0.5rem 3rem; border-left: 3px solid #ccc; }.author { font-size: 1.2rem; padding-right: 0.5rem; text-align: right; }.author::before { content: "("; }.author::after { content: ")"; }
 <:-- Importing React and ReactDOM --> <script crossorigin src="https.//unpkg.com/react@17/umd/react.production.min:js"></script> <script crossorigin src="https.//unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script> <!-- This is where your component will be mounted --> <div id="app"> </div>

Or, if you prefer functional components and hooks:或者,如果您更喜欢功能组件和挂钩:

 const RandomQuoteMachine = () => { const [quotes, setQuotes] = React.useState([]); const [currentQuote, setCurrentQuote] = React.useState(null); React.useEffect(() => { fetch("https://type.fit/api/quotes").then(response => response.json()).then(result => { setQuotes(result); setCurrentQuote(result[Math.floor(Math.random() * result.length)] || null); }) }, [setQuotes, setCurrentQuote]); const getRandomQuote = React.useCallback(() => { const newQuote = quotes[Math.floor(Math.random() * quotes.length)] || null; setCurrentQuote(newQuote) }, [quotes, setCurrentQuote]); return ( <div> <blockquote> { currentQuote && currentQuote.text || '' } </blockquote> <p className = "author"> { currentQuote && currentQuote.author || 'unknown' }</p> <button onClick = { () => getRandomQuote() }> get a new quote from the list </button> </div> ); } ReactDOM.render(<RandomQuoteMachine />, document.getElementById('app'));
 * { font-family: sans-serif; } blockquote { font-size: 2rem; font-style: italic; }.author { font-size: 1rem; text-align: right; }.author::before { content: "("; }.author::after { content: ")"; }
 <script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script> <div id="app"> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM