refactor: Refactor Article component to use hooks

This commit is contained in:
2025-07-07 17:29:10 +00:00
committed by Tanner Collin
parent 633429c976
commit 7ac4dfa01c

View File

@@ -1,32 +1,24 @@
import React from 'react'; import React, { useState, useEffect, useMemo } from 'react';
import { useParams } from 'react-router-dom';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
import localForage from 'localforage'; import localForage from 'localforage';
import { sourceLink, infoLine, ToggleDot } from './utils.js'; import { sourceLink, infoLine, ToggleDot } from './utils.js';
class Article extends React.Component { function Article({ cache }) {
constructor(props) { const { id } = useParams();
super(props);
const id = this.props.match ? this.props.match.params.id : 'CLOL';
const cache = this.props.cache;
if (id in cache) console.log('cache hit'); if (id in cache) console.log('cache hit');
this.state = { const [story, setStory] = useState(cache[id] || false);
story: cache[id] || false, const [error, setError] = useState(false);
error: false, const [pConv, setPConv] = useState([]);
pConv: [],
};
}
componentDidMount() {
const id = this.props.match ? this.props.match.params.id : 'CLOL';
useEffect(() => {
localForage.getItem(id) localForage.getItem(id)
.then( .then(
(value) => { (value) => {
if (value) { if (value) {
this.setState({ story: value }); setStory(value);
} }
} }
); );
@@ -35,31 +27,27 @@ class Article extends React.Component {
.then(res => res.json()) .then(res => res.json())
.then( .then(
(result) => { (result) => {
this.setState({ story: result.story }); setStory(result.story);
localForage.setItem(id, result.story); localForage.setItem(id, result.story);
}, },
(error) => { (error) => {
this.setState({ error: true }); setError(true);
} }
); );
} }, [id]);
pConvert = (n) => { const pConvert = (n) => {
this.setState({ pConv: [...this.state.pConv, n]}); setPConv(prevPConv => [...prevPConv, n]);
} };
render() { const nodes = useMemo(() => {
const id = this.props.match ? this.props.match.params.id : 'CLOL'; if (story && story.text) {
const story = this.state.story;
const error = this.state.error;
const pConv = this.state.pConv;
let nodes = null;
if (story.text) {
let div = document.createElement('div'); let div = document.createElement('div');
div.innerHTML = story.text; div.innerHTML = story.text;
nodes = div.childNodes; return div.childNodes;
} }
return null;
}, [story]);
return ( return (
<div className='article-container'> <div className='article-container'>
@@ -83,17 +71,19 @@ class Article extends React.Component {
<div className='story-text'> <div className='story-text'>
{Object.entries(nodes).map(([k, v]) => {Object.entries(nodes).map(([k, v]) =>
pConv.includes(k) ? pConv.includes(k) ?
v.innerHTML.split('\n\n').map(x => <React.Fragment key={k}>
<p dangerouslySetInnerHTML={{ __html: x }} /> {v.innerHTML.split('\n\n').map((x, i) =>
) <p key={i} dangerouslySetInnerHTML={{ __html: x }} />
)}
</React.Fragment>
: :
(v.nodeName === '#text' ? (v.nodeName === '#text' ?
<p>{v.data}</p> <p key={k}>{v.data}</p>
: :
<> <React.Fragment key={k}>
<v.localName dangerouslySetInnerHTML={v.innerHTML ? { __html: v.innerHTML } : null} /> <v.localName dangerouslySetInnerHTML={v.innerHTML ? { __html: v.innerHTML } : null} />
{v.localName == 'pre' && <button onClick={() => this.pConvert(k)}>Convert Code to Paragraph</button>} {v.localName === 'pre' && <button onClick={() => pConvert(k)}>Convert Code to Paragraph</button>}
</> </React.Fragment>
) )
)} )}
</div> </div>
@@ -108,6 +98,5 @@ class Article extends React.Component {
</div> </div>
); );
} }
}
export default Article; export default Article;