Search code examples
javascriptreactjsreact-lifecycle

Invoke `componentDidUpdate` on form submit


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.


Solution

  • 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>
            )
        }
    }