2

I want to get the users input of a form with two drop-downs, and store it inside a global variable using react. I looked at reacts docs on how to create forms, and manipulate their code a little bit to have two drop-downs, but can't get it to save the variable as a global variable and print that global variable onto the screen. Unfortunately, there was an error when I clicked the second submit button (The first button did nothing). Here was the error: TypeError: this is undefined handleSubmit src/App.js:55 52 | } 53 | handleSubmit(event) { 54 | event.preventDefault(); > 55 | two = this.state.value | ^ 56 | } 57 | 58 | render() { – . Here was my code inside App.js:

import React from "react";
import "./App.css";
var one = "";
var two = "";

class FlavorFormOne extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: "coconut" };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({ value: event.target.value });
  }
  handleSubmit(event) {
    event.preventDefault();
    one = this.state.value
  }

  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <label>
            Pick your favorite flavor:
            <select value={this.state.value} onChange={this.handleChange}>
              <option value="grapefruit">Grapefruit</option>
              <option value="lime">Lime</option>
              <option value="coconut">Coconut</option>
              <option value="mango">Mango</option>
            </select>
          </label>
          <input type="submit" value="Submit" />
        </form>
        
      </div>
    );
  }
}

class FlavorFormTwo extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: "GrabeFruit" };
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    this.setState({ value: event.target.value });
  }
  handleSubmit(event) {
    event.preventDefault();
    two = this.state.value
  }

  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <label>
            Pick your favorite flavor:
            <select value={this.state.value} onChange={this.handleChange}>
              <option value="grapefruit">Grapefruit</option>
              <option value="lime">Lime</option>
              <option value="coconut">Coconut</option>
              <option value="mango">Mango</option>
            </select>
          </label>
          <input type="submit" value="submit"/>
        </form>
        
      </div>
    );
  }
}

function App() {
  return (
    <>
    <FlavorFormOne />
    <FlavorFormTwo />
    {one}
    {two}
    </>
  );
}

export default App;
Rayyan
  • 82
  • 7
  • In `FlavorFormTwo`, you don't bind `handleSubmit` to `this`. Try adding `this.handleSubmit = this.handleSubmit.bind(this);` in your constructor. – Nathan Chu Nov 22 '20 at 01:14
  • It won't print the output onto the screen after saving inside a global varible. – Rayyan Nov 22 '20 at 13:23

2 Answers2

3

you didn't pass the event

try onSubmit={(e)=>this.handleSubmit(e)}

also onChange={(e)=>this.handleChange(e)}

  • It won't print the output onto the screen after saving inside a global varible. – Rayyan Nov 22 '20 at 13:22
  • I think your way to declare the global variable in React Js is incorrect. Look at this https://stackoverflow.com/questions/51240409/how-to-declare-global-variables-in-react-js. Or try to make {one} and {two} as state. – Ihsan Fajar Ramadhan Nov 22 '20 at 13:48
0

There were a couple things that needed to be fixed in your code. The first was this.handleSubmit = this.handleSubmit.bind(this); needed to be added in FlavorFormTwo's constructor, as I mentioned in the comments. The second was your handling of global variables. React won't re-render a component when a global variable changes, but it will re-render when the state is changed with setState. This is the reason why react state doesn't update when using this.state =. Instead, I added onSubmit as a prop to both, and inside both handleSubmit functions I added this.props.onSubmit(this.state.value). I changed the App component to a class, and added functions for handleOneSubmit and handleTwoSubmit that set the state of app. Try it online: https://codesandbox.io/s/vibrant-smoke-tsgri?file=/src/App.js

import React from "react";
import "./App.css";

class FlavorFormOne extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: "coconut" };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({ value: event.target.value });
  }
  handleSubmit(event) {
    event.preventDefault();
    this.props.onSubmit(this.state.value);
  }

  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <label>
            Pick your favorite flavor:
            <select value={this.state.value} onChange={this.handleChange}>
              <option value="grapefruit">Grapefruit</option>
              <option value="lime">Lime</option>
              <option value="coconut">Coconut</option>
              <option value="mango">Mango</option>
            </select>
          </label>
          <input type="submit" value="Submit" />
        </form>
      </div>
    );
  }
}

class FlavorFormTwo extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: "GrabeFruit" };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({ value: event.target.value });
  }
  handleSubmit(event) {
    event.preventDefault();
    this.props.onSubmit(this.state.value);
  }

  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <label>
            Pick your favorite flavor:
            <select value={this.state.value} onChange={this.handleChange}>
              <option value="grapefruit">Grapefruit</option>
              <option value="lime">Lime</option>
              <option value="coconut">Coconut</option>
              <option value="mango">Mango</option>
            </select>
          </label>
          <input type="submit" value="submit" />
        </form>
      </div>
    );
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { one: "", two: "" };
    this.handleOneSubmit = this.handleOneSubmit.bind(this);
    this.handleTwoSubmit = this.handleTwoSubmit.bind(this);
  }
  handleOneSubmit(value) {
    this.setState({ one: value });
  }
  handleTwoSubmit(value) {
    this.setState({ two: value });
  }
  render() {
    return (
      <>
        <FlavorFormOne onSubmit={this.handleOneSubmit} />
        <FlavorFormTwo onSubmit={this.handleTwoSubmit} />
        {this.state.one}
        {this.state.two}
      </>
    );
  }
}

export default App;

Nathan Chu
  • 635
  • 1
  • 3
  • 19