T
T
TechnicaL2020-06-25 20:37:50
React
TechnicaL, 2020-06-25 20:37:50

What is the correct way to do routing in React when using React-router-dom?

I'm new to development and there's a lot of confusion in my head right now.
I have nested components and the most child component should display user data.
When the page is refreshed, the data disappears, because when the component is rendered, a request about the user from the address bar flies to the server, profile/:userId? in the nested component, the following address line /profile/about is obtained.
Instead of /profile/number, the request is /profile/string and the response is 404 because no such page exists.
The same happens when the page is reloaded.
If I insert /${match.url}/about into the path, then the correct path /profile/7777/about is obtained, but the page is not rendered and on reload it gives an error Failed to execute 'pushState' on 'History': A history state object with URL

In App.js parent component is wrapped in withRouter and withRouter is wrapped in BrowserRouter

app.js

class App extends React.Component{  componentDidMount(){   this.props.is_initialization()      }    
 render(){    
     let{initializationSeccess} = this.props
  if(!initializationSeccess) return <>LOADING</>
    return (<div className="grid" >        
            <Switch>             
               <Route exact path= {`/profile/:userId?`}  render={() => <ProfileConteiner  />} />                            
            </Switch>
           </div>
        ); } }      
 let setStateToProps = (store) => {
     return{
        initializationSeccess: store.initialization.success,     
     }
 }    
let ContainerApp = compose(  
    withRouter,    
    connect(setStateToProps , { is_initialization })
)(App); 
let NovaKraina = () => {
return <BrowserRouter> <Provider store={store}> <ContainerApp/> </Provider>  </BrowserRouter>
}
export default NovaKraina


This is the ProfileContainer component at the time of mounting the component, it renders the Profile component and calls the sanitizer in componentDidMount which sends a profile/UsersID GET request to the north to render the user profile
Component's ProfileContainer

class ProfileConteiner extends React.Component<PropsTypes, OwnStateProps> {  
    drawComponent (){       
         let {setUsers, match, generalId, history} = this.props         
                    setUsers(match.params.userId, generalId,)  
     }
     componentDidMount() {        
        this.drawComponent()      
     }    
    render() { 
        let {userProfileId} = this.props
        return  <Profile {...this.props}  userProfileId={userProfileId}  onSubmit={this.submit}  />
    }
}
let mapStateToProps = (state: RootReducerType) : MapStateProps  => {   
        return {                         
            profile: getProfile(state),  
            generalId: getOwnUserId(state)
}}
export default compose(
    withRouter,
    withAuthRedirect,
    connect<MapStateProps, MapDistpathProps, OwnStateProps, RootReducerType>(mapStateToProps,  {  setUsers  })
)(ProfileConteiner)



This component contains links to components that should be rendered.
Component profile
const Profile:React.FC<PropsType> = (props: PropsType) => { 
 let {  profile,  userProfileId} = props
 let match = useRouteMatch(); 
    return (<div className={d.wrap}>        
            <User userData={profile} />
            <ProfileUserNavigation  /> 
            <Switch> 
                <Route exact path={`/profile/`} render={() => <ProfilePage profile={profile} /> }/>             
                <Route exact path={`/profile/about`} render={() => <AboutContainer />} />
                <Route exact path={`/profile/about_overview`} render={() => <AboutContainer />} />
                <Route  path={'/profile/about_work_and_education'} render={() => <AboutContainer />} />
            </Switch>
          </div>
    )
}
export default Profile;


ProfileUserNavigation is the navigation for profile
ProfileUserNavigation component
const ProfileUserNavigation: React.FC<UserNavigationType> = (props: UserNavigationType) => {  
    return (
        <div className={d.nav}>
            <div className={d.nav_info}>
                <NavLink to={`/profile/`} activeStyle={{backgroundColor: "rgb(46, 46, 46)"}}>Хроника</NavLink>
                <NavLink to={ `/profile/about`} activeStyle={{backgroundColor: "rgb(46, 46, 46)"}}>Информация</NavLink>
                <NavLink to={ '/profile/friends'} activeStyle={{backgroundColor: "rgb(46, 46, 46)"}}>Друзья</NavLink>  
                <NavLink to={ '/profile/fotos'} activeStyle={{backgroundColor: "rgb(46, 46, 46)"}}>Фото</NavLink>
            </div>            
            <div className={d.nav_edit_profile}>Редактировать проф...</div>
        </div>
    )
}
export default ProfileUserNavigation;


Request to the server to get user data
api.ts
export const profileApi = { 
  profileUserId: (userId: number | null) => {  
    return instance.get<ProfileResponseUserId>(`profile/` + userId)
  },
}


Thanks for any help

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question