简体   繁体   中英

Why am I getting a TypeError when start typing in my input? - ReactJS

I am creating a Recipe Box app but I have a problem with the input for the recipe name when I'm creating a recipe.

When I start to type in it I get the following error message: 类型错误

This is my states in my main component:

class RecipeBoxContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      recipes: [
        {
          name: "test123",
          products: ["313", "dasd", "dasfg"]
        },
        {
          name: "test",
          products: ["product", "product 2", "product 2", "product 3"]
        }
      ],
      count: 1,
      productInputValues: {
        name: "",
        products: []
      }

    };
    this.renderInputs = this.renderInputs.bind(this);
    this.addInput = this.addInput.bind(this);
    this.deleteRecipe = this.deleteRecipe.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleNameChange = this.handleNameChange.bind(this);
  }

The function where the error comes from:

renderInputs() {
    debugger;
    let inputs = [];
    for (let i = 0; i < this.state.count; i++) {
      inputs.push(
        <div key={i}>
          <FormControl
            type="text"
            value={this.state.productInputValues.products[i] || ""}
            onChange={this.handleChange.bind(this, i)}
            placeholder={"Product " + (i + 1)}
          />
          <Button onClick={this.removeInput.bind(this, i)}>Remove</Button>
        </div>
      );
    }
    return inputs || null;
  }

My onChange input handlers:

  handleChange(i, event) {
    debugger;
    let productInputValues = this.state.productInputValues.products;
    productInputValues[i] = event.target.value;

    this.setState({
      productInputValues: {
        products: productInputValues
      }
    });
  }

  handleNameChange(event) {
        debugger;
    this.setState({
      productInputValues: {
        name: event.target.value
      }
    });
  }

and with this component, I'm creating the recipes:

class AddRecipe extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      showModal: false
    };
    this.close = this.close.bind(this);
    this.open = this.open.bind(this);
  }

  close() {
    this.setState({ showModal: false });
  }

  open() {
    this.setState({ showModal: true });
  }

  render() {
    return (
      <div>
        <Button bsStyle="primary" bsSize="large" onClick={this.open}>
          Add Recipe
        </Button>
        <Modal show={this.state.showModal} onHide={this.close}>
          <Modal.Header closeButton>
            <Modal.Title>Add Recipe</Modal.Title>
          </Modal.Header>
          <form onSubmit={this.props.onSubmit}>
            <Modal.Body>
              <FormGroup controlId="RecipeName">
                <ControlLabel>Recipe</ControlLabel>
                <FormControl
                  type="text"
                  placeholder="Recipe Name"
                  onChange={this.props.handleNameChange}
                />
              </FormGroup>
              <FormGroup controlId="formControlsTextarea">
                <ControlLabel>Products</ControlLabel>
                {this.props.renderInputs()}
              </FormGroup>
              <Button onClick={this.props.addInput}>Add Product</Button>
            </Modal.Body>
            <Modal.Footer>
              <Button bsStyle="success" type="submit">
                Next station: Kitchen
              </Button>
              <Button onClick={this.close}>Close</Button>
            </Modal.Footer>
          </form>
        </Modal>
      </div>
    );
  }
}

Full code + working example

You are changing object productInputValues ..it does have products. In handleChange and handleNameChange use spread operator ..or copy object correctly.

handleChange(i, event) {
    debugger;
    let productInputValues = 
     this.state.productInputValues.products;
     productInputValues[i] = event.target.value;

this.setState({
  productInputValues: {...this.state.productInputValues,
    products: productInputValues
  }
});
}
handleNameChange(event) {
    debugger;
this.setState({
  productInputValues: {...this.state.productInputValues,        
 name : event.target.value
  }
 });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM