Reputation: 133
I am trying to convert markdown files to html. I am able to do so with a package called showdown, but the goToPage component continuously runs as seen by hundreds of console logs continuously flowing.
The below code allows the user to type in a filename in the url and an express server returns a markdown file. React then converts it to html and displays that html. I'm aware that the return div is empty after the first run and depends on the state being updated when the data has been fetched, but I don't know how to break the loop after that.
class App extends Component {
state = { myFile: '' }
constructor(props) {
super(props);
this.goToPage = this.goToPage.bind(this);
}
goToPage = ({ match }) => {
fetch('/' + match.params.filename)
.then((res) => res.text())
.then((text) => {
console.log(text);
var fileContents = text;
var showdown = require('showdown'),
converter = new showdown.Converter(),
markdown = fileContents,
html = converter.makeHtml(markdown);
console.log(html);
this.setState({ myFile: html });
})
.catch(err => {
console.log(err);
});
return (
<div dangerouslySetInnerHTML={{ __html: this.state.myFile }} />
)
}
render() {
return (
<Router>
<Route path="/:filename" component={this.goToPage} />
</Router >
);
}
}
export default App;
I'm quite new to React, so I don't know if my goToPage should even be in the same class- still learning the basics. I'd love to know if I'm doing something stupid.
Upvotes: 2
Views: 880
Reputation: 19194
<Route path="/:filename" component={this.goToPage} />
This line asks the router to render whatever is in the this.goToPage
as the component on the said route. But if you check the goToPage
function, it uses this.setState
that rerenders the browser. The route tries to render the goToPage
function again and the cycle repeats.
Instead, what you need to do is to render another component in route /:filename
and make sure that fetch runs only once.
<Route path="/:filename" component={MarkdownConverter} />
Now, inside MarkdownConverter
component:
class MarkdownConverter extends Component {
this.state = {
myFile: ""
}
componentDidMount() {
// All the logic for fetch and convert goes here.
}
render() {
return (
<div dangerouslySetInnerHTML={{ __html: this.state.myFile }} />
);
}
}
Upvotes: 1