7

I have get some data from db , when I console log them it works nice. and also when I stringfy the passed props are OK and displayed on the screen as they are expected.

import axios from 'axios'
import { URL } from '../../../../config'
import Header from './header'

class NewArticle extends Component {
    state = {
        article: [],
        team: []
    }
    componentWillMount() {
        axios.get(`${ URL }/articles?id=${ this.props.match.params.id }`)
        .then( res => {
            let article = res.data[ 0 ]
            console.log( res.data[ 0 ] )
            //{
                //     author: "John Secada",
                //     date: "10/12/2018",
            // }           
            axios.get( `${ URL }/teams?id=${ article.team }` )
            .then( res => {
                this.setState({
                    article,
                    team: res.data[0]
                })
                console.log( res.data[0] )
                // {
                //     id: 3,
                //     logo: "nets.png",
                //     name: "Nets",
                //     poll: "false",
                //     stats: {wins: 23, defeats: 12}
                // }
            } )
        } )
    }
    render(){
        let article = this.state.article
        let team = this.state.team
        return(
            <div>
                 <Header
                    teamData={ team }
                    date={ article.date }
                    author={ article.author }
                    />
                { JSON.stringify(article,team) }
            </div>
        )
    }
}
export default NewArticle

the Header component which recieves the props:

import React from 'react'
const Header = props => {
    return (
        <div>    
            { console.log( props) }
            {/* {teamData: Array(0), date: undefined, author: undefined} */}    
        </div>
    )
}
export default Header 

So why they are undefined, when I pass them as props to a Header component?

Amir Meyari
  • 573
  • 4
  • 9
  • 30
  • 2
    First use `componentDidMount` instead of `componentWillMount` for side effects(api call), on first render `
    ` will not have `article` data, it is after api data resolves, data is available, you need to check if `article` data is available and only then render `
    ` component.
    – tarzen chugh Jun 18 '19 at 16:01
  • 1
    Also `componentWillMount ` is a legacy life cycle method, you should not use these methods as they will not work after React V17 https://reactjs.org/docs/react-component.html#unsafe_componentwillmount – Mohd Hassan Jun 18 '19 at 16:12

3 Answers3

9

Because you have async request and when Header is being mounted you don't have this data yet.

Try this:

   render(){
        const article = this.state.article
        const team = this.state.team

        if(!article && !article.date && !article.author) {
          return null;
        }

        if(!team) {
          return null;
        }

        return(
            <div>
                 <Header
                    teamData={ team }
                    date={ article.date }
                    author={ article.author }
                    />
                { JSON.stringify(article,team) }
            </div>
        )
    }
Evghenii
  • 225
  • 1
  • 9
  • I also suggest to not use ```componentWillMount``` as it will be deprecated. https://reactjs.org/docs/react-component.html#unsafe_componentwillmount – Evghenii Jun 18 '19 at 16:19
5

Inside the componentWillMount you are using axios which returns a promise and is asynchronous. The problem is that you are rendering the <Header/> before the data is fetched from the API. To Avoid this you can update your render function like this.

function render() {
 let article = this.state.article;
 let team = this.state.team;
 return (
  <div>
   {team.length ? (
    <Header teamData={team} date={article.date} author={article.author} />
    ) : (
    'Loading Data...'
   )}
  {JSON.stringify(article, team)}
  </div>
);
}
Mohd Hassan
  • 184
  • 8
2

First of all, @Evghenii 's answer is correct.

Here's the more smart and recommended approach to handle conditional rendering.

You can use Higher Order Components to handle conditional rendering in reactjs.

For more details: Higher Order Components with Conditional Rendering in React.

Diamond
  • 3,470
  • 2
  • 19
  • 39