This entry is a discussion of what I experienced when attempting to build a blog from scratch using the React framework. The concepts involved were: fetch(), promises, and the Context API.
I started with components that simply rendered HTML, just to get the React code to work. For example, the Masthead component:
class Masthead extends React.Component
{
constructor(props)
{
super(props);
}
render()
{
return(
...HTML markup...
);
}
}
This was pretty straightforward.
The next part was getting the context API mechanism to work. I got the Provider and the Consumer components working, but I got hung up on the actual click action that triggered the message pass.
The reason was because the syntax for the message pass in the button consumer that I was using was actually executing the callback function, rather than passing it as a message to be executed in the provider component:
// syntax I was using:
<button onClick={{context.updateMessage(this.props.fileName)}}>
// corrected syntax:
<button onClick={()=>{context.updateMessage(this.props.fileName)}}>
This fixed the error, and the context API mechanism was working.
Now that the state and component communication mechanisms were working, I could add the fetch() and promise code to the Provider. The updateMessage() callback function calls the fetch() method to read the contents of a file whos name is based on the prop, then set the Provider state message prop to that text content:
<ReactContext.Provider value=
{{
state: this.state,
updateMessage: ( pageID ) =<
{
const that = this;
fetch(new Request('./' + pageID + '.htm'))
.then(function(response)
{
return response.text();
})
.then(function(textStr)
{
that.setState({ message: textStr });
})
}
}}>
{this.props.children}
</ReactContext.Provider>
Note the 'that' = 'this' assignment. This places the 'this' object within the scope of the updateMessage callback function. The file name prop gets passed into the callback, then passed to the fetch() function.
The final problem to solve was to get the dangerouslySetInnerHTML method to accept the context state and render the text as HTML. I tried everything, and could not get it to work.
AND THEN...I found this.
html-react-parser is a 3rd party library that is available on a CDN, and works in this use case. Yes, it may not be as safe as some other libraries like it, but the blog does not accept user input, so input to the code is strictly controlled on the server side.
You reference it like this:
<script type="text/javascript" src="https://unpkg.com/html-react-parser@latest/dist/html-react-parser.min.js"></script>
And call it in your React Context API Consumer code like this:
<ReactContext.Consumer>
{(context) => HTMLReactParser(context.state.message)}
</ReactContext.Consumer>
At this point, I no longer needed to get the dangerouslySetInnerHTML method to work, and the project was complete.