Refresh React Component after changing data from modal dialog box

Purvish Oza picture Purvish Oza · Sep 27, 2018 · Viewed 7.4k times · Source

I am building a small web application to learn React and exposed to an issue now. My task is to click on a particular city name and go to another component where that name of the city will be displayed.

On that second component, I have one modal dialog box, where I can change the name of the city. While doing this, my component is still displaying the old city name rather the new one which I chose from the modal dialog box. When I refresh the page manually it does show that new name. I am very new to react and getting confused in such stuff. What should I do to render an updated city name?

SecondTable Component:(Where I want to display the name of the city)

class SecondTable extends Component {


state = {
    data: [(visible: false), (city: null)]
  };

   componentDidMount() {
    console.log(this.props);
    let id = this.props.match.params.city_id;
     axios
      .get("http://100.124.69.3:8080/api/v1/cities/" + id)
      .then(res => {
        this.setState({ city: res.data.name });
        console.log(res);
      });
    console.log(this.state.city);
  }

  render() {
    return <div className="align1">{this.state.city}</div>;
  }
}

Component for Modal dialog box from where i chose new city:

class FacilityModal extends Component {


state = {
    cities:[],
  }

  componentDidMount()
  {
    console.log(this.props.visa)
    await axios.get('http://100.124.68.1:8080/api/v1/cities' ).then(res => {
      this.setState({cities:res.data})

    });

  }



render() {
       let posts = (
         <div >All Facilities (NCAL)
               <div className = 'Modal'>
                   {this.state.cities.map(city =>
                       {
                         return <Link to = {'/'+city.id} key = {city.id} onClick = {this.props.onCancel}> {city.name} </Link>
                       })}
               </div>
               </div>

          );

    return (

      <div>
        <Modal
          title="Change Facility"
          visible={this.props.visible}
           onCancel={this.props.onCancel}
          footer={null}
        >
        <div>{posts}</div>
        </Modal>
      </div>
    );
  }

My Home Component for the initial list of cities:

class Home extends Component{


 state = {
    cities:[],
    name:''
  }

   componentDidMount()
  {

     axios.get('http://100.124.68.1:8080/api/v1/cities').then(res => {
      this.setState({cities:res.data})

    });

  }

  render(){
    let postList = this.state.cities.map(city =>
    {
      return (

          <div key = {city.id}>
          <p>
        <Link to = {'/'+city.id}>{city.name}</Link></p>
        </div>
      )
    })
    return(


        <div className = 'align'>All Facilities (NCAL)
<div class="hr-sect">OR</div>
   <div className = 'Modal1'>
            {postList}
        </div>
      </div>


    )
  }

Routes for component:

render() {
return (


<div >
      <BrowserRouter>
        <div className="App">
          <Header />
            <Switch>
                <Route exact path='/' component={Home} />
                <Route path='/users' component={TableData} />
                <Route path='/:city_id' component={SecondTable} />
            </Switch>
        </div>
  </BrowserRouter>

Answer

nfadili picture nfadili · Sep 27, 2018

You are managing state within each of your components independently. The simple answer to your question is that you need to update state that both of your components can then render from. You can accomplish this in many ways, from using a state management framework like redux or mobx, to using purely react state and reorganizing your component tree. Without seeing the parent component of the two components you showed, it's hard to say exactly how you should do it. The gist of it would be: pass a function as props to your modal component that will fire when a city is selected. That function should update the state for the 'selected city'. You then would be passing the 'selected city' as props to your SecondTable component. When state is updated, a re-render is triggered which in turn would pass that new 'selected city' state as props to your SecondTable component and it would re-render as well with the updated value.

This blog post by the react team is an excellent introduction on how to approach problems with react. I can't recommend it enough. https://reactjs.org/docs/thinking-in-react.html