History push undefined при использовании props в Axios getData в React

Я пытаюсь сделать этот компонент сообщений многоразовым, добавив реквизиты от родителя. Мои реквизиты - это «путь» и «фильтр». У меня есть путь к моей базе данных, которую я хочу обновить, и фильтр, который позволяет мне отфильтровывать данные из этой базы данных. Он распечатывает список сообщений на основе имени пути и фильтра. Это работает нормально, мой компонент «Сообщения» отображается правильно.

Однако, когда я добавляю функцию щелчка к своему единственному посту, чтобы он переходил к компоненту «FullPost» на основе post.id, я получаю сообщение об ошибке, в котором говорится, что «Не удается прочитать свойство« push »of undefined». Когда я не использую реквизиты, а жестко кодирую значения, вместо этого он работает нормально, и щелчок работает должным образом, он переходит к компоненту FullPost и URL-адресу на основе идентификатора.

Я пробовал распечатать this.props.history, но он показывает undefined. Я не уверен, как это определить и почему добавление реквизита делает это неопределенным.

Родитель называет это так:

<Route path="/food" exact render={() => <Posts pathname="/posts" filter="food" />} />

Кажется, что метод render () не включает в себя жизненные крючки, поэтому он не включает историю? Однако я не уверен, как включить мои реквизиты, если я не использую render () вместо component = {} в Route.

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

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 () {
        //console.log('posts props: ', this.props.pathname, ', posts filter: ', this.props.filter, ', this props: ', this.props);
        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
            });

            console.log( 'history: ', this.props.history );
        })
        .catch(error => {
            console.log(error);
        });
    }


    postSelectedHandler = ( id ) => {
        this.props.history.push( this.props.match.url + '/' + 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.title}
                         dek={post.dek}
                         clicked={() => this.postSelectedHandler( post.id )}     />
                );
            });
        };
        return (
            <Aux>
                 <div className={classes.PostList}>
                     <h2 className={classes.PostListTitle}>{this.props.filter}</h2>
                    {posts}
                </div>
            </Aux>
        )
    }
}

export default Posts;

person user2986096    schedule 22.05.2018    source источник


Ответы (1)


Вы пропустили параметры маршрута:

<Route path="/food" exact render={(routeProps) => <Posts pathname="/posts" filter="food" {...routeProps} />} />

или (если вам нужно просто history):

<Route path="/food" exact render={({history}) => <Posts pathname="/posts" filter="food" history={history} />} />
person Alex    schedule 22.05.2018
comment
Спасибо, что сработало, я только что нашел начальный ответ, но не знал, что вы можете настроить таргетинг только на историю, это очень удобно. - person user2986096; 22.05.2018
comment
Да, я также не вижу, связали ли вы контекст компонента с getData () - если вы этого не сделаете, это не сработает, потому что это необходимо для правильного вызова this.setState () - person Alex; 22.05.2018
comment
Вы имеете в виду добавить это? this.getData = this.getData.bind (это); - person user2986096; 23.05.2018
comment
Ага, через constructor - person Alex; 23.05.2018