2

I have a class component as follows:

class App extends Component {
    constructor(props){
        super(props);
        this.state = {
            abc: '',
            someQuery: ''
        }
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleChange = this.handleChange.bind(this);
    }

    componentDidUpdate(){
        fetch(`/someLink/${this.state.abc}`)
        .then(response => {
            return response.json();
        }).then(data => {
            this.setState({
                someQuery: data.xxx
            });
        });
    }
    handleSubmit(e){
        const target = e.target;
        const value = target.value;

        this.setState({
            abc: value
        })
        e.preventDefault();
    };
    handleChange(e){
        const target = e.target;
        const value = target.value;

        this.setState({
            abc: value
        });
    };
    render(){
        return(
            <form onSubmit={this.handleSubmit}>
                <input name='abc' value={this.state.abc} onChange={this.handleChange} />
                <input type="submit" value="Submit" />
            </form>

            <div>{this.state.abc} is currently accessing data from {this.state.someQuery}</div>
        )
    }
}

How do I run componentDidUpdate() every time I update the value of an input field and clicking the submit button?

The above invokes the life-cycle but due to the setState within handleChange() too, the life-cycle is invoked the moment I type something and doesn't wait till the submit button is clicked.

Removing the setState from handleChange() makes the input field value not editable anymore (cant type on the input field).

I need the input field value appended to the api link in the life-cycle but I can't seem to figure out the right way to do this.

AndrewL64
  • 15,794
  • 8
  • 47
  • 79

1 Answers1

4

You can add any method in component class and call it on submit. componentDidUpdate is not right place to do such thing especially setting state is crime :D

class App extends Component {
    constructor(props){
        super(props);
        this.state = {
            abc: '',
            someQuery: ''
        }
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleChange = this.handleChange.bind(this);
    }

    doSommething (value){
        fetch(`/someLink/${value}`)
        .then(response => {
            return response.json();
        }).then(data => {
            this.setState({
                someQuery: data.xxx
            });
        });
    }
    handleSubmit(e){
        const target = e.target;
        const value = target.value;

        this.setState({
            abc: value
        })
        e.preventDefault();
        doSommething(value);
    };
    handleChange(e){
        const target = e.target;
        const value = target.value;

        this.setState({
            abc: value
        });
    };
    render(){
        return(
            <form onSubmit={this.handleSubmit}>
                <input name='abc' value={this.state.abc} onChange={this.handleChange} />
                <input type="submit" value="Submit" />
            </form>

            <div>{this.state.abc} is currently accessing data from {this.state.someQuery}</div>
        )
    }
}
Zohaib Ijaz
  • 21,926
  • 7
  • 38
  • 60
  • 1
    I read somewhere that api fetches should be called within the `componentDidUpdate' lifecycle hence why I went with the original approach above. Thanks for the help Zohaib. – AndrewL64 May 26 '18 at 00:50
  • @AndrewL No, it is `componentDidMount` and not the `componentDidUpdate`. and it is for cases when you want to get data from api which will be rendered soon but not that kind of api call that will be frequently fetched on some click or some event. Use simple method to do so like the one in your code `onSubmit` – Zohaib Ijaz May 26 '18 at 00:54
  • So for an API that does not renders data instantly, I should use componentDidMount? – AndrewL64 May 26 '18 at 00:58
  • 1
    @AndrewL No,sorry about my wrong choice of words. let me explain. e.g. if you want to show a list of users and data will come from api, you need to get data in `componentDidMount` by calling a reusable method which will actually fetch data from api. and you can call that reusable method later on some event like on delete user which will update user list data – Zohaib Ijaz May 26 '18 at 01:04
  • Oh ok. Thanks for the explanation Zohaib – AndrewL64 May 26 '18 at 01:05