1

I'm assigning values inside my componentWillMount like shown in below

componentWillMount() {
    /*this.props.fetchMetaData(this.props.url);*/
    axios.get(`https://api.microlink.io/?url=${this.props.url}`)
        .then(res => {
            this.metaData = res;
            console.log("99999999999 ", this.metaData.data.data);
            this.image = this.metaData.data.data.image.url;
            this.title = this.metaData.data.data.title;
            this.description = this.metaData.data.data.description;
            this.metaurl = this.metaData.data.data.url;
            console.log("title ", this.title);
        });
}

And i'm trying to show the values inside my render() as follows.

render() {
    console.log("title ", this.title);
    return (
        <div>
            <a className="previewUrlContainer float_left unchange_div border"
               href={metaurl}
               target="_blank">
                <img className="previewImage margin_bottom10px" src={this.image}></img>
                <div className="margin_bottom10px font_bold">{this.title}</div>
                <div className="margin_bottom10px medium_font">{this.description}</div>
                <div className="margin_bottom10px small_font">{this.metaurl}</div>
            </a>
        </div>
    );
}

But I get undefined values even though I've checked all the values inside componentWillMount. How can i use the values inside componentWillMountwithin render().

1

2 Answers 2

4

Since you have a async call in componentWillMount, you response is only ready after the initial render and when you just set the class variables a re-render is not called and hence the result is not getting reflected in UI. You should use state to store the data. Also you must have your API call in componentDidMount lifecycle. You can check this for more details

Use componentWillMount or componentDidMount lifecycle functions for async request in React

state= {
    image: '',
    title: '',
    description: '',
    metaurl: ''
}
componentDidMount() {


    /*this.props.fetchMetaData(this.props.url);*/
    axios.get(`https://api.microlink.io/?url=${this.props.url}`)
        .then(res => {

            this.setState({
                image: res.data.data.image.url;
                title: res.data.data.title;
                description : res.data.data.description;
                metaurl : res.data.data.url;
           })

        })

    }

render() {

    return (

        <div>

            <a className="previewUrlContainer float_left unchange_div border"
               href={metaurl}
               target="_blank">

                <img className="previewImage margin_bottom10px" src={this.state.image}></img>
                <div className="margin_bottom10px font_bold">{this.state.title}</div>
                <div className="margin_bottom10px medium_font">{this.state.description}</div>
                <div className="margin_bottom10px small_font">{this.state.metaurl}</div>


            </a>

        </div>
    );
}
Sign up to request clarification or add additional context in comments.

Comments

2

You should store those data in the state. Call setState in componentWillMount (recommended to change to componentDidMount for clearer intention).

Demo:

class App {
  state = {
    res: null,
  }
  componentDidMount() {
    axios.get(...).then(res => this.setState({res}))
  }
  render() {
    return <div>{JSON.stringify(this.state.res)}</div>
  }
}

2 Comments

Could someone please explain why everyone is recommending componentDidMount instead of componentWillMount in this kind of situations?
@ShamseerAhammed componentWillMount should not have side effects: reactjs.org/docs/react-component.html#unsafe_componentwillmount. These lifecycle methods are getting replaced by React Hooks btw.

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.