First things first. Don't use setTimeout, but rather use the callback function of setState to execute code after the state is set ensuring it has been modified. Calling the callback function will guarantee the state is changed before that code in the callback is executed.
from the official docs:
setState() enqueues changes to the component state and tells React
  that this component and its children need to be re-rendered with the
  updated state. This is the primary method you use to update the user
  interface in response to event handlers and server responses.
setState() does not always immediately update the component. It may
  batch or defer the update until later. This makes reading this.state
  right after calling setState() a potential pitfall. Instead, use
  componentDidUpdate or a setState callback (setState(updater,
  callback)), either of which are guaranteed to fire after the update
  has been applied.
setState(stateChange[, callback])
The second parameter to setState() is an optional callback function
  that will be executed once setState is completed and the component is
  re-rendered. Generally we recommend using componentDidUpdate() for
  such logic instead.
So, instead of:
if (this.state.downloadFile === true) {
  this.setState({ downloadFile: false });
  setTimeout(() => {
    // execute code, or redirect, or whatever
  }, 100);
}
you should do:
if (this.state.downloadFile === true) {
  this.setState({ downloadFile: false }, () => {
    // execute code, or redirect, or whatever
  });
}
Now, for your specific problem
Set headers in your server side
You can set the Content-Disposition header to tell the browser to download the attachment:
from here:
In a regular HTTP response, the Content-Disposition response header is
  a header indicating if the content is expected to be displayed inline
  in the browser, that is, as a Web page or as part of a Web page, or as
  an attachment, that is downloaded and saved locally.
Set it like this:
('Content-Disposition: attachment; filename="/tmp/PASOP180901.txt"');
Force download from the client
There are multiple ways to force the download from the client, but this is the only one I've tried.
For this to work, you have to have the content of text somehow in the client (your express route can return it for example) and create a filename for the file that will be downloaded.
let element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
Basically you are creating an empty link component, setting the data attribute to it with the text's content, attaching the link to the body, clicking the link and then removing the link from the body.
Open the link in a new tab
Opening the link in a new tab will trigger the download as well:
window.open('/api/downloadFile');
Redirect programatically
Have a look at this question in SO
You can do this:
this.props.history.push("/api/downloadFile")?
If cannot access this.props.history you can import { withRouter } from 'react-router-dom'; and export default withRouter(yourComponent); to access it.