简体   繁体   中英

Re-render child after parent state change with get request

So I'm a beginner with react and I was wondering how to re-render the child after setting the state in the parent (from the child). Here's a code sample. I have a function that calls a GET request using Axios and when I press the button in the child component ideally it will update the state in the parent and also re-render the child but it only does the former.

Parent:

class Parent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            data: []
        }
    }

    fetchData = () => {
       axios
            .get(url)
            .then(res => this.setState({data: res.data}))
    }


    Render() {
        return (<Child data={this.state.data} fetchData={this.fecthData}/>)
    }

    // ...

Child:

class Child extends Component {
    // ...

    render() {
        const { data, fetchData } = this.props
        // render data
        return <button onClick={fetchData}>Change data then fetch</button>
    }
}

Also, are you supposed to make a local state in the Child and set it as a copy of the Parent's state or just passing it down as a prop is okay?

Your parent component holds the data and the child uses it. It seems to me you're doing it the right way. Here is a fully working example: Codesandbox

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: []
    };
    this.updateData = this.updateData.bind(this);
  }

  async fetchData() {
    const response = await fetch("https://jsonplaceholder.typicode.com/posts");
    return response.json();
  }

  updateData() {
    this.setState({ data: [] }) // Creates a flicker, just so you see it does refresh the child
    this.fetchData().then((res) => this.setState({ data: res }));
  }

  render() {
    return <Child data={this.state.data} onAction={this.updateData} />;
  }
}

Note I renamed your child prop fetchData into onAction (I don't know what's the name of the action that triggers a refresh, could be onRefresh ). It's always best to see components props with separation between data attributes and event attributes .

Even standard components have it this way: <input value={user.firstname} onChange={doSomething} /> . So, better to prefix events by on , then the parent decides what to do with it. It's not the child's concern.

class Child extends Component {
  render() {
    const { data, onAction } = this.props;

    return (
      <>
        <button onClick={onAction}>Change data then fetch</button>
        {data.map((item) => (
          <div key={item.id}>
            {item.id} - {item.title}
          </div>
        ))}
      </>
    );
  }
}

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