Kyle Batchelor
Kyle Batchelor

Reputation: 41

React Fails to render new component after state change

The following fails to render the selected Component even when the state is updated. I assumed it might have to do with the shallow check react makes, however after forcing a re-render the page still shows the originally selected component and not the new component. The only way I got it to correctly function was by changing the activeService state to <></> then changing it to the correct Service Component. Any help would be appreciated.

import React, { Component } from "react";
import AquireServices from "./AquireService";
import Navigation from "./Navigation";
import Service from "./Service";

class App extends Component{
  constructor(props) {
    super(props);
    this.state=({
      services: {},
      activeService: <></>
    });
  }

  async componentDidMount() {
    try{
        let services = await AquireServices();
        this.setState({ services: services });
    } catch(error) {
        console.log(error);
    }
  }

  selectedField = async (field) => {
    let service = this.state.services[field];
    if(service){
      this.setState({ activeService: <Service props={service} /> });
    }
  }

  render() {
    return(
      <Box sx={{ padding: 0, display: 'flex' }}>
        <Navigation selectFunction={this.selectedField.bind(this)}/>
        {this.state.activeService}
      </Box>
    );
  }
}

export default App;

Initial

Displaying Correct Field

Displaying previous Field after state change

Output after changes: enter image description here

Upvotes: 0

Views: 56

Answers (1)

Bms bharadwaj
Bms bharadwaj

Reputation: 533

No no, you don't need to store a component and try to render it via the state object.

If you observe, the only thing that is changing when you select things in the Navigation Box is the service props.

So, instead of storing a whole component, you can just store the selected service's props. Then, you can pass that props directly to the Service component in render(), like this:

class App extends Component{
  constructor(props) {
    super(props);
    this.state=({
      services: {},
      activeService: undefined
    });
  }

  async componentDidMount() {
    try{
        let services = await AquireServices();
        this.setState({ services: services });
    } catch(error) {
        console.log(error);
    }
  }

  selectedField = async (field) => {
    let service = this.state.services[field];
    if(service){
      this.setState({ activeService: service });
    }
  }

  render() {
    const {activeService} = this.state;
    return(
      <Box sx={{ padding: 0, display: 'flex' }}>
        <Navigation selectFunction={this.selectedField.bind(this)}/>
        {activeService ? <Service props={activeService}> : undefined}
      </Box>
    );
  }
}

Upvotes: 1

Related Questions