Mayank0255 / Stackoverflow-Clone-Frontend

Clone project of a famous Q/A website for developers built using MySQL, Express, React, Node, Sequelize :globe_with_meridians:
https://stackoverflow-clone-client.vercel.app
MIT License
546 stars 209 forks source link

I try to modify react app and get link to Question inside sidebar component #24

Closed a-nai closed 3 years ago

a-nai commented 3 years ago
import React from 'react';
import { NavLink } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { getPost } from '../../redux/posts/posts.actions';
import { ReactComponent as GlobalIcon } from '../../assets/Globe.svg';
import './SideBar.styles.scss';

const SideBar = ({ getPost, post: { title, id } }) => (
    <div className='side-bar-container'>
        <div className='side-bar-tabs'>

            <NavLink exact activeClassName='active' className='home-link nav_link' to='/' >
                <p>Home</p>
            </NavLink>

            <div className='public-tabs'>
                <p className='title fc-light'>PUBLIC</p>
                <NavLink activeClassName='active' className='icon-link nav_link' to='/questions' >
                    <p>
                        <GlobalIcon className='icon' />
                        Stack Overflow
                    </p>
                </NavLink>
                <NavLink activeClassName='active' className='link nav_link' to={id} >
                    <p>Tags</p>
                </NavLink>
                <NavLink activeClassName='active' className='link nav_link' to='/users' >
                    <p>${ title }</p>
                </NavLink>
                <NavLink activeClassName='active' className='link nav_link' to='/jobs' >
                    <p>Jobs</p>
                </NavLink>
            </div>
            <div className='teams-tabs'>
                <p className='title fc-light'>TEAMS</p>
            </div>
        </div>
    </div>

);
SideBar.propTypes = {
    getPost: PropTypes.func.isRequired,
    post: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
    post: state.post
});

export default connect(mapStateToProps, { getPost })(SideBar);

I get error

TypeError: Cannot read property 'pathname' of undefined
(anonymous function)
/Users/andrejeremcuk/Stackoverflow-Clone/modules/NavLink.js:50
  47 |   resolveToLocation(to, currentLocation),
  48 |   currentLocation
  49 | );
> 50 | const { pathname: path } = toLocation;
     | ^  51 | // Regex taken from: https://github.com/pillarjs/path-to-regexp/blob/master/index.js#L202
  52 | const escapedPath =
  53 |   path && path.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");

I modify sidebar in that way:

`import React from 'react';
import { NavLink } from 'react-router-dom';

import { ReactComponent as GlobalIcon } from '../../assets/Globe.svg';
import './SideBar.styles.scss';

const SideBar = () => (
    <div className='side-bar-container'>
        <div className='side-bar-tabs'>

            <NavLink exact activeClassName='active' className='home-link nav_link' to='/' >
                <p>Home</p>
            </NavLink>

            <div className='public-tabs'>
                <p className='title fc-light'>PUBLIC</p>
                <NavLink activeClassName='active' className='icon-link nav_link' to='/questions' >
                    <p>
                        <GlobalIcon className='icon' />
                        Stack Overflow
                    </p>
                </NavLink>
                <NavLink activeClassName='active' className='link nav_link' to='/tags' >
                    <p>Tags</p>
                </NavLink>
                <NavLink activeClassName='active' className='link nav_link' to='/users' >
                    <p>Users</p>
                </NavLink>
                <NavLink activeClassName='active' className='link nav_link' to='/jobs' >
                    <p>Jobs</p>
                </NavLink>
            </div>
            <div className='teams-tabs'>
                <p className='title fc-light'>TEAMS</p>
            </div>
        </div>
    </div>

);

export default SideBar;`
Mayank0255 commented 3 years ago

@a-nai

So, the thing is you need to call the getPost action in the hooks which would be useEffect specifically and the getPost action has a parameter for the id of the post which you will need to pass in the useEffect() as well. getPost returns details of a single post and it fetches that by id.

And kindly properly explain that what exactly do u want to do for which I might be able to help out

a-nai commented 3 years ago

TypeError: Cannot read property 'pathname' of undefined

  47 |   resolveToLocation(to, currentLocation),
  48 |   currentLocation
  49 | );
> 50 | const { pathname: path } = toLocation;
     | ^  51 | // Regex taken from: https://github.com/pillarjs/path-to-regexp/blob/master/index.js#L202
  52 | const escapedPath =
  53 |   path && path.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");

Still error

import React, { Fragment, useEffect, useState } from 'react';
import { NavLink } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { getPost } from '../../redux/posts/posts.actions';
import { ReactComponent as GlobalIcon } from '../../assets/Globe.svg';
import './SideBar.styles.scss';

const SideBar = ({ getPost, post: { post, id , title },match }) => {
    useEffect(() => {
        getPost(match.params.id);
    }, [ getPost ]);

   return loading|| post===null ? <Spinner type='page' width='75px' height='200px'/> : <div className='side-bar-container'>
        <div className='side-bar-tabs'>

            <NavLink exact activeClassName='active' className='home-link nav_link' to='/' >
                <p>Home</p>
            </NavLink>

            <div className='public-tabs'>
                <p className='title fc-light'>PUBLIC</p>
                <NavLink activeClassName='active' className='icon-link nav_link' to='/questions' >
                    <p>
                        <GlobalIcon className='icon' />
                        Stack Overflow
                    </p>
                </NavLink>
                <NavLink activeClassName='active' className='link nav_link' to={id} >
                    <p>Tags</p>
                </NavLink>
                <NavLink activeClassName='active' className='link nav_link' to='/users' >
                    <p>${ title }</p>
                </NavLink>
                <NavLink activeClassName='active' className='link nav_link' to='/jobs' >
                    <p>Jobs</p>
                </NavLink>
            </div>
            <div className='teams-tabs'>
                <p className='title fc-light'>TEAMS</p>
            </div>
        </div>
    </div>

};
SideBar.propTypes = {
    getPost: PropTypes.func.isRequired,
    post: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
    post: state.post
});

export default connect(mapStateToProps, { getPost })(SideBar);

or that error

TypeError: Cannot read property 'params' of undefined
(anonymous function)
src/components/SideBar/SideBar.component.jsx:12
   9 | 
  10 | const SideBar = ({ getPost, post: { post, loading, id , title },match }) => {
  11 |     useEffect(() => {
> 12 |         getPost(match.params.id);
  13 |     }, [ getPost ]);
  14 | 
  15 |    return loading|| post===null ? <Spinner type='page' width='75px' height='200px'/> : <div className='side-bar-container'>
Mayank0255 commented 3 years ago

@a-nai

So, you might be getting the undefined error when you are in route where there doesn't exists a parameter. The match.param.id will be able to get the post id only if you have opened the post as at that moment the url get's updated showing the id at the top. On other pages it would give this error for which you will need to handle the error somehow.

a-nai commented 3 years ago
import React, { Fragment, useEffect, useState } from 'react';
import { NavLink } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Spinner from '../../components/Spinner/Spinner.component';
import { getPost } from '../../redux/posts/posts.actions';
import { ReactComponent as GlobalIcon } from '../../assets/Globe.svg';
import './SideBar.styles.scss';

const SideBar = ({ getPost, post: { post, loading, id , title }, postId }) => {
    useEffect(() => {
        getPost(postId);
    }, [ getPost ]);

I change to postId - and error gone - but sidebar constantly loading - seems can't get postId

Mayank0255 commented 3 years ago

@a-nai

I recommend to you to first learn Reactjs properly as you are not aware of the redux state management that good that is why you are trying to import whatever you want but that's not how it works you need to send postId as parameter from somewhere only then you can import it. That's just the gist of the problem you need to first learn react state management with redux properly then test the app inside out to know what method does what.