DEV Community

Алексей Шиманович
Алексей Шиманович

Posted on

How to properly implement the post functionality?

Hello. I wrote the functionality of a post and would like to hear some peer review on the implementation. Perhaps somewhere unproductive or fundamentally wrong decision. In addition, I ran into a problem - likes and views are not always displayed.

import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import root from '../../modules/root';
import _ from 'lodash';
import './post.css'; // styles

// icons ↓
import likeIcon from '../../icons/like.svg';
import likedIcon from '../../icons/liked.svg';
import viewIcon from '../../icons/view.svg';

function Post(props) {
    const [data, setData] = useState({});
    const [likes, setLikes] = useState();
    const [views, setViews] = useState();

    async function takeData() {
        const _data = await (await fetch(`${root}/api/article/${props.id}`)).json(); // *
        setData(_.get(_data, 'article[0]'));
        setLikes(_.get(data, 'likes'));
        setViews(_.get(data, 'whatches'));
        console.log(data.likes)
        console.log(likes, views)
    }

    function checkLiked() {
        return _.get(data, 'whoLiked', []).includes(localStorage.getItem('userID'));
    }

    function act(action) {
        if (action !== "like" && action !== "view") {
            throw Error('arg');
        }

        return async function() {
            if (action === 'like' && checkLiked()) {
                return;
            }

            const _data = await(await fetch(`${root}/api/article/act`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    user: localStorage.getItem('user'),
                    id: _.get(data, 'id', ''),
                    action
                })
            })).json();

            setLikes(likes + 1);
        }
    }

    useEffect(() => {
        takeData();
    }, []);

    return (
        <div className="post">
            <div className="top">
                <div className="author">
                    <div className="logo">
                        <img src={`${root}/api/upload/get/${_.get(data, 'user[0].picture')}` || 'https://i.imgur.com/EIXMLcv.png'} alt="" />
                    </div>
                    <div className="name-blog"><Link to={`/profile/${_.get(data, 'user[0].id')}`}>{_.get(data, 'user[0].user_name')}</Link> =&gt; <Link to={`/blog/${_.get(data, 'blog[0].id')}`}>{_.get(data, 'blog[0].name')}</Link></div>
                </div>
                <div className="content">
                    <Link to={`/article/${_.get(data, 'id')}`}>
                        <div className="body">
                            {_.get(data, 'body')}
                        </div>
                    </Link>
                </div>
            </div>
            <div className="tech">
                <div className="likes" onClick={act("like")}>
                    <img className={checkLiked() ? 'b' : 'a'} src={checkLiked() ? likedIcon : likeIcon} alt="" />
                    <div className="text">{likes}</div>
                </div>
                <div className="watches">
                    <img src={viewIcon} alt="" />
                    <div className="text">{views}</div>
                </div>
            </div>
        </div>
    );
}

export default Post;
Enter fullscreen mode Exit fullscreen mode

Аn asterisk in the code marks the location where the post data was received. The resulting object looks something like this:

image

Does this forum provide for such a discussion format?

Top comments (0)