Access State within React componentDidMount()

Hi guys,

I’m having a hard time figuring out why my code doesn’t work.

What I am trying to do is to concatenate inputVal in this request let myRequest = "https://en.wikipedia.org/w/api.php?action=query&origin=*&list=search&srsearch="+ this.state.inputVal + "&format=json";
In order to only change the srsearch part of the request according to what the user has entered in the input field.

However, when using this method, it does not recognize the srsearch property and throws an error telling me that it needs srsearch property to work.

I’ve tried using this.inputVal instead, by doing that, the property is recognized, but undefined is returned…

Here is my component:

import React from 'react';
import styled from 'styled-components';

const InputDiv = styled.div `
    text-align: center;
    margin-top: 1em;
`

const StyledParagraph = styled.p `
    color: white;
    text-align: center;
    margin-top: 1em;
`

const StyledInput = styled.input.attrs({
    type: "text"
})`
    margin: auto;
    border: 4px solid orange;
    background-color: transparent;
    border-radius: 25px;
    color: white;
    padding: 3px 1em;

    &:focus {
        outline: 5px white;
    } 
`;

export default class SearchArticle extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            inputVal: "",
            articles: []
        }

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    componentDidMount() {
        let myRequest = "https://en.wikipedia.org/w/api.php?action=query&origin=*&list=search&srsearch="+ this.state.inputVal + "&format=json";
        fetch(myRequest)
        .then(res => res.json())
        .then((data) => {
          this.setState({ articles: data })
        })
        .catch(console.log)
      }

    handleChange(e) {
        let targetEvent = e.target.value;
        this.setState({
            inputVal: targetEvent
        })
    }

    handleSubmit(e) {
        e.preventDefault();
        console.log(this.state.inputVal);
        console.log(this.state.articles);
    }

    render() {
        return (
            <InputDiv>
                <form onSubmit={this.handleSubmit}>
                    <StyledInput onChange={this.handleChange} />
                </form>
                <StyledParagraph>Type something to search</StyledParagraph>
            </InputDiv>
        );
    }
}

Can anyone help me understand what I am doing wrong please?
I am fairly new to manipulating React State and using Lifecycle methods… And I feel like I did not understand properly how this works…

Thanks in advance :slight_smile:

a. The input has no value prop (this should be inputVal)
b. Once that’s done, the input will have an empty value to start off with anyway, so when the component mounts, that variable will be an entry string that you’re using in the URL given to fetch. Logic should be:

  • Component has an input value and data in state, both start empty
  • onChange, update the input value with whatever the value of the input is
  • onSubmit, update the data value with the result of fetching the data

Thanks for the answer.

I am a bit confused tho.

It feels like I am doing this part, there:

    componentDidMount() {
        let myRequest = "https://en.wikipedia.org/w/api.php?action=query&origin=*&list=search&srsearch="+ this.state.inputVal + "&format=json";
        fetch(myRequest)
        .then(res => res.json())
        .then((data) => {
          this.setState({ articles: data })
        })
    }

You are doing it when the component mounts (hence the name of the method). So you’re just running fetch as soon as that component appears on the browser page, that’s the only time fetch is executed, and inputVal is just an empty string at that point. You’re not using componentDidMount for anything useful (you don’t need to do anything when the component mounts) so just delete it.

Oh okay, I see, so basically, in this case, I shouldn’t do my API calls within the componentDidMount, since they will change as soon as a user search for something.

edit: sorry I wrote my answer when you were editing yours.

1 Like

Worked like a charm, thanks again for the explanations :smiley:

1 Like