Noble Polygon
Noble Polygon

Reputation: 806

ReactJS: Conditional rendering submits form data before handleSubmit function

I have a form that upon completion renders a button with form data. The form takes two inputs: 1. Title (text rendered in button) & 2.) URL for the button.

The form works with the conditional statement if I paste in a URL. However if I begin manually typing a URL, it generates the button based on the first character I type because the string is no longer empty.

export default class URLButton extends Component {
  constructor(props) {
    super(props)

    this.state = {
      links: [],
      url: '',
      title: ''
    }
  }

// onChange
  onChange = (e) => {
    e.preventDefault(e)
    this.setState({
      [e.target.name]: e.target.value
    })
  }

  // onSubmit

  onSubmit = e => {
    e.preventDefault()
  }


  render() {
    if (this.state.url === "") {
      return (
        <>
          <form onClick={this.onSubmit}>
            <input
              name="title"
              type="text"
              placeholder="add button text"
              onChange={e => this.setState({ title: e.target.value })}
            />
            <input
              name="url"
              type="url"
              placeholder="your-link.com"
              onChange={e => this.setState({ url: e.target.value })}
            />
            <br />
          </form>
          <button type="submit">Submit</button>
        </>
      )
    } else {
      return (
        <>
          <div>
            <a href={this.state.url} className="link-button" target="_blank" rel="noopener noreferrer">{this.state.title}</a>
          </div >
        </>
      )
    }
  }
}

Since the onChange and onSubmit function works, I've narrowed it down to the conditional statement if (this.state.url === "") {... I've tried setting it to null and false instead of an empty string but the form doesn't render if I try those statements.

Upvotes: 0

Views: 2776

Answers (3)

Alberto Perez
Alberto Perez

Reputation: 2922

Yeah, you're right, your problem is that, when you typed something, the url state is not empty anymore, you'll have to validate that the url is valid in order to submit the form, I've made a StackBlitz with the solution of the problem, I hope this helps.

Upvotes: 2

ibtsam
ibtsam

Reputation: 1720

If you want to finish typing and than generate the button you can change your onChange to onBlur as

<input
   name="url"
   type="url"
   placeholder="your-link.com"
   onBlur={e => this.setState({ url: e.target.value })}
/>

Now when you type out and blur out of input than button will be gernerated

Hope it helps

Upvotes: 1

Artemiy Vereshchinskiy
Artemiy Vereshchinskiy

Reputation: 132

First of all you should pass yours input states to input:

...
<input
   name="url"
   type="url"
   value={this.state.url} // here
   placeholder="your-link.com"
   onChange={e => this.setState({ url: e.target.value })}
/>
...

By this edit onChange would pass to set state not only character you've just wrote, but all of previous charecters plus last one.

Then look at your code here:

...
if (this.state.url === "")
...

It would be false right after the FISRT charecter in state.url setted. If you need to check for correct URL you should use regexp in if condition, to check if state.url looks like correct url by your expectations and ONLY after that render the other part of component.

Upvotes: 0

Related Questions