0

I have a list of items. When user clicks on one of the items, it takes him to a page with only this element. Like this:

Questions component:

render() {
    return (
        <section id='loopContainer' className='display-question'>
            <div className='wrapper'>
                <ul style={{listStyleType: 'none'}}>
                    {
                        this.state.questions.map(question => {
                            return (
                                <li key={question.id}>
                                    <h3>Kategoria: {question.category}</h3>
                                    <p>Poziom: {question.level}</p>
                                    <p>Punkty: {question.pointAmount + question.pointBoost}</p>
                                    <img alt='' style={{width: '20%'}} src={question.photoURL}/>
                                    <p>{question.workText}</p>
                                    <Link to={`/question/${question.id}`}
                                          style={{display: 'block', margin: 'auto'}}>Rozwiaz to zadanie
                                    </Link>
                                </li>
                            )
                        })
                    }
                </ul>
            </div>
        </section>
    )
}

Question component:

render() {
    return (
        this.state.questions.map(question => {
            return (
                <section key={question.id} className='display-question'>
                    <div className='wrapper show-grid'>
                        <h3>Kategoria: {question.category}</h3>
                        <p>Poziom: {question.level}</p>
                        <p>Punkty: {question.pointAmount + question.pointBoost}</p>
                        <Col xs={12} md={6}>
                            <img alt='' style={{width: '100%'}}
                                 src={question.photoURL}/>{/*Need 100% for the ratio*/}
                            <p>{question.workText}</p>
                        </Col>
                        <Col xs={12} md={6}>
                            <form onSubmit={this.handleSubmit}>
                                <textarea name="textAnswer" id="textAnswer" style={{
                                    width: '100%',
                                    height: '50vh',
                                    background: 'white',
                                    color: 'black'
                                }}/>
                                <input id="file-upload" type="file"/>
                                <Button type='submit' style={{display: 'block'}}>Wyslij odpowiedz</Button>
                            </form>
                        </Col>
                    </div>
                </section>
            )
        })
    )
}

This is how I'm trying to query the database:

const itemsRef = firebase.database().ref('Works')
                         .orderByChild('firebaseKey')
                         .equalTo(this.props.match.params.id);

The problem is in my Navigation component. Exactly here:

<Switch>
    <Route exact path="/about" component={AboutComponent}/>

    <Route exact path="/questions" render={
        () => (firebase.auth().currentUser === null ?
            <Redirect to='/'/> : <QuestionsComponent/>)
    }/>

    <Route exact path='/question/:id' render={
        () => (firebase.auth().currentUser === null ?
            <Redirect to='/'/> : <QuestionComponent/>)
    }/>

    <Route exact path="/" component={HomeComponent}/>
</Switch>

So the problem is, when I'm trying to get to the single element page, this throws an error:

<Route exact path='/question/:id' render={
    () => (firebase.auth().currentUser === null ?
        <Redirect to='/'/> : <QuestionComponent/>)
}/>

The error is: TypeError: this.props.match is undefined.

But if I do it like this:

<Route exact path='/question/:id' component={QuestionComponent}/>

All works well.

So why is the first way erroring out, while the second is just fine? And how do I make the second way work?

1 Answer 1

1

When you use the render prop, it gives you the Router props as params which you need to pass down to you custom component which uses them like

<Route exact path="/questions" render={
    (props) => (firebase.auth().currentUser === null ?
        <Redirect to='/'/> : <QuestionsComponent {...props}/>)
}/>

In case of a component prop, Route automatically passes the Router props to the underlying component.

Sign up to request clarification or add additional context in comments.

2 Comments

@alex.iron, no you do not,match param is passed to the Route along with Router params when you write <QuestionsComponent {...props}/>,
What error do you receive, also not that the render function takes props as a argument which you pass down

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.