Q:

how to render returned data on prop change in react

I am having trouble figuring out how to get an API call to re-render to the screen. I have an apiCall function that passes this.state and changes the state via passed ref but it does not trigger a rerender on the props change.
searchBody.js
 class SearchBody extends Component {
constructor(props) {
      super(props)
      const queryString = require('query-string');
      const queryTerm = queryString.parse(this.props.location.search);
      this.state = { urlSearchTerm: queryTerm.search,
                      searchTerm: '',
                      loaded: false,
                      buttonClicked: null,
                      apiData: [],
                      tableHeaders: [],
                      tableRows: []
                    }
      // check if URL has search term if so pass term for apiCall
      if (this.state.urlSearchTerm) {
         this.state.searchTerm = this.state.urlSearchTerm
      }

      this.handleChange = this.handleChange.bind(this)
      this.handleSubmit = this.handleSubmit.bind(this)
    }

// capture input text field to state variable
handleChange = searchTerm => event => {
  this.setState({ searchTerm: event.target.value })
  //console.log(this.state.searchTerm)
  }

// handle form submission
handleSubmit = (event) => {
  console.log('Inside HandleSubmit')
  console.log('button clicked update url to /?search=' + this.state.searchTerm)
  this.props.history.push('/?search=' + this.state.searchTerm);
  this.setState({buttonClicked: true})
  event.preventDefault();
}
// load search from API if search term is in URL
componentDidMount() {
  console.log('Inside compDidMount')
  if (this.state.urlSearchTerm){
      this.setState({apiData: apiCall(this.state)})
  }
 }

render() {
  const { classes } = this.props;

  let table = ''
  //check if API has loaded data and show results if true
if (this.state.loaded){
  if (this.state.apiData.length === 0 && this.state.buttonClicked){
    table = 'No Results Found'
    //reset search button State
    this.setState({buttonClicked: false})
  } else {
    table = <TableData tableHead={this.state.tableHeaders} tableData={this.state.tableRows} />
    //reset search button State
    this.setState({buttonClicked: false})
  }
}
    return (

      <Fragment>
      <hr/>
       <form /*className={classes.container}*/ noValidate autoComplete="off" onSubmit={this.handleSubmit} >
          <TextField
              id="search"
              label="Search field"
              type="search"
            /*  className={classes.textField}*/
              margin="normal"
              onChange={this.handleChange('search')}
            />
            <Button color='primary' letiant="outlined" type="submit" >Search DB</Button>
        </form>

          <h1>Results: </h1>
              {table}
        </Fragment>
          )
  }

}
export default SearchBody

methods.js
// break API data into arry of data for table component rows.
export const parseTableHeaders = input => {
  // console.log(input)
  if (input !== undefined && input.length !== 0) {
  let head = []
  for(let key in input[0]){  head.push(key);}
  //console.log(head)
  return head
}
}

///break API data into array of headers for table component
export const parseTableRows = (input) => {
  let rows = [];
  for(let o in input) {
      rows.push(Object.values(input[o]));
  }
  //console.log(head)
  return rows
}

//get api data from AWS
export function  apiCall(props) {
  const searchTerm = props.searchTerm
  let apigClientFactory = require('aws-api-gateway-client').default;

  const config =  {
                //apiKey: 'xxxx',
                invokeUrl:'https://xxxx.execute-api.us-east-2.amazonaws.com'
                }

  let apigClient = apigClientFactory.newClient(config);
  let params = {
        //This is where any header, path, or querystring request params go. The key is the parameter named as defined in the API
        //  userId: '1234',
        search_keyword: searchTerm
      };
      // Template syntax follows url-template https://www.npmjs.com/package/url-template
  let pathTemplate = '/beta/testDB'
  let method = 'GET';
  let additionalParams = {
      //If there are any unmodeled query parameters or headers that need to be sent with the request you can add them here
      headers: { },
      queryParams: {
        search_keyword: searchTerm
              }
    }
    apigClient.invokeApi(params, pathTemplate, method, additionalParams)
      .then(function(result){
          //This is where you would put a success callback
          console.log('apiCall Returned. searchTerm; ', searchTerm)
          console.log(result)
          props.loaded = true
          props.tableHeaders = parseTableHeaders(JSON.parse(result.data))
          props.tableRows = parseTableRows(JSON.parse(result.data))
          return JSON.parse(result.data)
      }).catch( function(result){
          //This is where you would put an error callback
      })

}

Am I structuring the code wrong? My understanding is that when a prop changes it will force a re-render. Should I pass the "this.state.apiData" into apiCall instead of the entire state like this? 
apiCall(this.state.apiData)

This is running within componentDidMount() I believe this is the correct location to call an API, but it's not re-rendering upon callback. I can see in the debugger the state variables are updating as expected.
Should I set a return variable in apiCall() and have the return value update the state within the componentDidMount()? Would this force a re-render once the data is returned?
something like this?
this.setState({apiData: apiCall()})

If I return this.state.apiData from apiCall() and have it parse the table headers and rows inside apiCall, when the state variable is returned will this force an update? 

A:

Eric Hasselbring helped me get to this answer.
I was calling apiCall() and it was not returning anything inside of componentDidMount. I added return before the methods.js apigClient.invokeAPI() so that it would return the result of the function
  return apigClient.invokeApi(params, pathTemplate, method, additionalParams)
      .then(function(result){
          //This is where you would put a success callback
          console.log('apiCall Returned. searchTerm; ', searchTerm)
          console.log(result)
          debugger
          props.tableHeaders = parseTableHeaders(JSON.parse(result.data))
          props.tableRows = parseTableRows(JSON.parse(result.data))
          return JSON.parse(result.data)
      }).catch( function(result){
          //This is where you would put an error callback
      })

then I updated my function call from within SearchBody.js to 
componentDidMount() {
  console.log('Inside compDidMount')
  if (this.state.urlSearchTerm){
      apiCall(this.state).then(apiResponse => this.setState({
        loaded: true,
        apiData: apiResponse
      })
    )
  }
 }

So now apiCall returns a result from a promise and the apiCall is now a promise because of the .then function added. this allows the state to be changed inside of componentDidMount so that react sees there was a prop change and re-renders.

