Kumar R
Kumar R

Reputation: 471

React: Need to call parent to re-render component

I create a table with rows and sub-rows . When i delete a sub-row i need to re-render the whole component.

import React from 'react';
import ReactDOM from 'react-dom';
import auth from './auth'

export class FormList extends React.Component{

  constructor(props) {
    super(props);
    auth.onChange = this.updateAuth.bind(this)
    this.state = {results: []};
  }

  componentWillMount() {
    auth.login();
  }

  // call to get the whole list of forms for react to re-render.
  getForms() {
    if(this.state.loggedIn) {
      $.get(call server url, function(result) {
        this.setState({
             results: result.data.forms
        });
      }.bind(this));
    }
  }

  updateAuth(loggedIn) {
    this.setState({
     loggedIn: loggedIn
    });
    this.getForms()
  }

  componentDidMount() {
    this.getForms()
  }

  render() {
    return (
    <FormTable results={this.state.results} /> 
    )
 }
};

class FormTable extends React.Component{

  render() {
    return ( 
      <table className="forms">
       <thead>
         <tr>
            <th>Form Name</th>
            <th></th>
            <th style={{width: "40px"}}></th>
         </tr>
       </thead>
       {this.props.results.map(function(result) {
            return <FormItem key={result.Id} data={result} />;
        })}         
      </table>
    )
  }
};

class FormItem extends React.Component{
  render() {
    return (
      <tbody>
        <tr className="form_row">
          <td>{this.props.data.Name}</td>
          <td></td>
        </tr>
        {this.props.data.map(function(result) {
            return <FormTransaction key={result.Id} data={result} />;
        })} 
      </tbody>
    )
  }
};

class FormTransaction extends React.Component{

  render() { 
    return (
      <tr className="subform_row">
          <td>{this.props.data.date}</td>
          <td></td>
          <td data-enhance="false">
          <DeleteTransaction data={this.props.data.Id} />
      </tr>
    )
  }
};

class DeleteTransaction extends React.Component {
  constructor(props) {
    super(props);
    this.state = {Id:props.data};
    this.handleDelete = this.handleDelete.bind(this);
   }

   // deletes a sub row and calls get forms to re-render the whole react.
   handleDelete(event) {
     $.ajax({
      url: server url + this.state.Id,
      type: 'DELETE',
      data: {},
      dataType: 'json',
      success: function(result, status) {
          console.log(this);
          // need to call get forms here
      },
      error: function(jqXHR, status, error) {
          console.log(jqXHR);
      }
     });*/
  }

  render() {
    return(
      <i className="danger" onClick = {this.handleDelete}>X</i>
    )
  }
};

ReactDOM.render(
  (<FormList/>),
  document.getElementById('react-forms')
);

So i need to call the getforms method after delete is successful from handledelete method.

I am pretty new to react as well as using es6 . I tried extending deletetransaction to formslist and call super.getForms . But that didnt work either. Any help is appreciated..

Upvotes: 11

Views: 16366

Answers (2)

stephen
stephen

Reputation: 1707

You might also pass down a function from the parent component to the child component via the props of the child component, then upon an action of function being executed in the child component, you could simply call the function that was passed in.

For instance:

var ParentComponent = React.createClass({
    update: function() {
        this.setState({somethingToUpdate: "newValue"});
        console.log("updated!");
    },
    render: function() {
      <ChildComponent callBack={this.update} />
    }
})

var ChildComponent = React.createClass({
    render: function() {
      <button onClick={this.props.callBack}>click to update parent</button>
    }
})

Upvotes: 12

Eduard Ghinea
Eduard Ghinea

Reputation: 87

Whenever you are trying to call this.setState inside another function it will not know you are trying to set the state.

For example, in your code you have $.get( ... function (response){ ... this.setState() .. }

Because this.setState is inside function (response) this will point to function(response) rather than pointing to the root class.

So what you need to do is to save this inside a variable right before the $.get call.

var self = this; and inside the function do self.setState( ... ) instead of this.setState( .. )

Hope it helps.

Upvotes: 0

Related Questions