简体   繁体   中英

How to re-render parent component on child component's button click

I am learning react and I would still consider myself to be a beginner. My goal is to click a button on my child component so that I could re render the parent component. This is the code I have.

Parent Component

import React, { Component } from 'react';
import Activity from './Components/Activity'

class App extends Component {
  state = {
    activity: ''
  }

  handleClick = () => {
    // I have read that forceUpdate is discouraged but this is just an example
    this.forceUpdate()
  }

  async componentDidMount() {
    const url = 'http://www.boredapi.com/api/activity/'
    const response = await fetch(url);
    const data = await response.json();
    this.setState({
      activity: data.activity
    })
  }

  render() {
    return (
      <div>
        <Activity act={this.state.activity} click={this.handleClick}/>
      </div>
    );
  }
}

export default App;

Child Component

import React, { Component } from 'react';

class Activity extends Component {

  render() {
    return (
      <div>
        <h1>Bored? Here is something to do</h1>
        <p>{this.props.act}</p>
        <button onClick={this.props.click}>Something Else</button>
      </div>
    );
  }
}

export default Activity;

As you can see I am trying to click a button so that I could get another fetch and a different activity renders on my child component. I am trying to keep my child component stateless but if keeping it stateless doesn't make sense or is just plain wrong I would love to know.

You can try to move fetching function outside componentDidMount

for the example:

  handleClick = () => {
    this.fetchdata();
  }

  async fetchdata(){
    const url = 'http://www.boredapi.com/api/activity/'
    const response = await fetch(url);
    const data = await response.json();
    this.setState({
      activity: data.activity
    })
  }

  componentDidMount() {
    this.fetchdata();
  }

You can make a class method for fetching the new activity,
Call it after the app first mounted with componentDidMount() and again when you call it from the child component Activity .

  • You should mentioned in the your question that the response body is different
    in each request you make.
import React, { Component } from 'react';
import Activity from './Activity'

class App extends Component {
  state = {
    activity: ''
  }

  handleClick = () => {
    this.getActivity()
  }

  componentDidMount() {
    this.getActivity();
  }

  async getActivity() {
    const url = 'https://www.boredapi.com/api/activity/'
    const response = await fetch(url);
    const data = await response.json();
    this.setState({
      activity: data.activity
    })
  }

  render() {
    console.log(this.state);
    return (
      <div>
        <Activity act={this.state.activity} click={this.handleClick}/>
      </div>
    );
  }
}

export default App;

Here is also a sandbox:
https://codesandbox.io/s/dreamy-noether-q98rf?fontsize=14&hidenavigation=1&theme=dark

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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