Показать полный пост, используя прямой маршрут, как передать значения в шаблон на основе имени маршрута? - PullRequest
0 голосов
/ 26 мая 2018

У меня есть простой проект React, в котором у меня есть список сообщений Posts.js и полный шаблон сообщения FullPost.js Posts.js я передаю slug и id , чтобы я мог отобразить URL.

Например, 'Еда ' имеет список сообщений.Я нажимаю на сообщение, и оно пропускает 'slug: морковь' и 'id: 2' до 'еда / морковь' .Этот 'id' пропущен, так что он может найти правильный путь к моей морковной записи в моей базе данных, т.е. 'mydatabase.com / food / posts / 2 /'

Это хорошо работает, однако, когда я обновляю страницу, 'slug' и 'id' , которые были переданы компоненту FullPost ранее исчезают .Кроме того, я хотел бы иметь возможность доступа к URL-адресу напрямую, например, если я введу 'www.mywebsite.com / food / carrots' , это загрузит мою почту с морковью.В настоящее время мой FullPost не загружается при обновлении или переходе непосредственно к URL-адресу сообщения.Есть ли способ загрузить сообщение из этих других точек входа?

Ниже приведен мой код:

Моя база данных:

posts:    
    0:
        slug: "beans"
        id: 1
    1:
        slug: "milk"
        id: 2
    2:
        slug: "carrots"
        id: 3

Posts.js: списокposts.

import React, { Component } from 'react';
import axios from '../../../axiosPosts';
import Aux from '../../../hoc/Aux/Aux';
import classes from './Posts.css';
import Post from '../../../components/Post/Post';

class Posts extends Component {

    state = {
        posts: []
    }

    componentDidMount () {
        this.getData(this.props.pathname, this.props.filter);
    }

    getData(pathname, filter) {
        axios.get(pathname + '.json')
            .then(response => {
                const post = response.data.filter(({category}) => category === filter);

                const updatedPosts = post.map(post => {
                    return {
                         ...post
                    }
                });

                this.setState({
                    posts: updatedPosts
                });          
            })
            .catch(error => {
                console.log(error);
            });
    }

    postSelectedHandler = ( slug, id ) => {
         const URL = `${this.props.match.url}/${slug}`;
         this.props.history.push({pathname: URL, id: id });
     }
     render () {
         let posts = <p style={{textAlign: 'center'}}>Whoops! Something went wrong.</p>;
        if(!this.state.error) {
            posts = this.state.posts.map(post => {
                return (
                    <Post 
                        key={post.id}
                        title={post.slug}
                        clicked={() => this.postSelectedHandler( post.slug, post.id )} />
                );
            });
        };
        return (
            <Aux>
                <div className={classes.PostList}>{posts}</div>
            </Aux>
        )
    }
}
export default Posts;

FullPost.js (фактическая публикация)

import React, { Component } from 'react';
import axios from '../../../axiosPosts';
import classes from './FullPost.css';

class FullPost extends Component {

state = {
    loadedPost: null,
}

componentDidMount () {
    const { location: {id} } = this.props;
    this.loadData(id);
}

loadData(id) {
    if ( id ) {
        if ( !this.state.loadedPost || (this.state.loadedPost && this.state.loadedPost.id !== +id) ) {
            axios.get( '/food/posts/' + (id - 1) + '.json' )
                .then( response => {
                    this.setState( { loadedPost: response.data, locationId: id } );
                });
            }
        }
    }
    render () {
        let post = <p style={{ textAlign: 'center' }}>Please select a Post!</p>;
        const { location: {id} } = this.props;
        if ( id ) {
            post = <p style={{ textAlign: 'center' }}>Loading...!</p>;
        }
        if ( this.state.loadedPost ) {
            post = (
                <div className={classes.FullPost}>
                    <h1 className={classes.Title}>{this.state.loadedPost.title}</h1>
                </div>
            );
        }
        return post;
    }
}

export default FullPost;

App.js: Main js

import React, { Component } from 'react';
import { Route, Switch } from 'react-router-dom';
import classes from './App.css';
import Layout from './hoc/Layout/Layout';
import Posts from './pages/Posts/Posts';
import FullPost from './pages/FullPost/FullPost';


class App extends Component {
    constructor(props) {
        super(props);
        console.log('[App.js] Inside Constructor', props);
    }
    render() {
        return (
            <div className={classes.App}>
                <Layout>
                    <Switch>
                        <Route path="/food/" exact component={Posts} />
                        <Route path="/food/:slug" exact component={FullPost} />
                        <Route render={() => <h1>Whoops! What you're looking for isn't here anymore.</h1>} />
                    </Switch>
                </Layout>
            </div>
         );
    }
}

export default App;

1 Ответ

0 голосов
/ 26 мая 2018

Вы должны использовать что-то вроде React Router .

В двух словах, ваша проблема в том, что в вашем коде отсутствует логика сопоставления URL (все будет работать одинаково, даже если вы нене менять URL вообще).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...