olo
olo

Reputation: 5271

reactjs fetch PUT value and pass value to state

How to re-fetch after <code>PUT</code>

class Mycomponent extends Component {
    state = {
        text: null
    }

    componentDidMount() {
        fetch("http://localhost:3000/books/4")
          .then(response => response.json())
          .then(data => this.setState({ text: data.title  // this data.value is "Learn Javascript" }));
    }

    fetchPUT(val) {
    fetch("http://localhost:3000/books/4", {
        method: "PUT",
        headers: {
            "Content-Type": "application/json; charset=utf-8"
        },
        body: JSON.stringify({ value: val })
        }).then(e => console.log(e));
    }

     onMouseDown = e => {
        this.setState({
          text: this.refs.myinput.value,
        });
        this.fetchPUT(this.refs.myinput.value);
    };
    render() {
        const { text } = this.state;
        return (
            <div>
                <input
                  type="text"
                  value={text}
                  onMouseLeave={this.onMouseLeave}
                  ref="myinput"
                />
            </div>
        )
     }
}

I'd like to sync this.text whenever I click button to PUT the value. so the flow is to fetch first then change value, click button PUT value, after PUT, then fetch again

Upvotes: 1

Views: 116

Answers (1)

Ajay Gaur
Ajay Gaur

Reputation: 5280

You don't have to fetch the data from backend to synchronise the value with the current text. Instead use setState callback in your onMouseDown as:

onMouseDown = e => {
        this.setState({
          text: this.refs.myinput.value,
        }, () => {
           this.fetchPUT(this.refs.myinput.value);
        });
    };

Here the state will be set before it makes a put call and as you're having the updated value, you don't have to fetch the value. When the component is unmounted and mounts again, it will fetch the updated value from your componentDidMount.

Read more here

Also

In the render function, use onChange instead of onMouseDown (Which you're not even using) because that would be less confusing. Use debounce so that you don't have to make many API calls on every change.

onChange = _.debounce((event) => {
   const text = event.target.value;
   this.setState({text}, () => {
       this.fetchPUT(text);
   })
}, 500)

render() {
        const { text } = this.state;
        return (
            <div>
                <input
                  type="text"
                  value={text}
                  onChange={this.onChange}
                />
            </div>
        )
     }

Upvotes: 2

Related Questions