最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to make dynamic state for multiple fields in react? - Stack Overflow

programmeradmin1浏览0评论
class Bills extends Component {
constructor(props) {
    super(props)
    this.state = {
        productName: '',
        price: 0,
        quantity: 0,
        noOfProductsField: 0
    }
}
handleChange = name => event => {
    this.setState({
        [name]: event.target.value,
    });
};

createFields = () => {
        const { classes } = this.props;
        let children = []
        for (let i = 0; i < this.state.noOfProductsField; i++) {
            children.push(
                <div>
                    <Select
                        className={classes.textField}
                         value = { this.state[i] }
                    onChange={this.handleChange('productName')}
                        displayEmpty
                        SelectProps={{
                            MenuProps: {
                                className: classes.menu,
                            }
                        }}>
                        <MenuItem value="" disabled>
                            Select Product
                           </MenuItem>
                        {this.state.products.map((option, ind) => (
                            <MenuItem key={ind} value={option.productName}>
                                {option.productName}
                            </MenuItem>
                        ))}
                    </Select>
                    <TextField className={classes.textField} placeholder='Price' type='number' onChange={this.handleChange('price')} />
                    <TextField className={classes.textField} placeholder='Quantity' type='number' onChange={this.handleChange('quantity')} />
                </div>
            )
        }
        return children
    }
}

I Have this function which is creating 3 input fields in for loop

  • productName
  • price
  • quantity

For Example if loop is running 2 times it will create 6 fields like image below:

So now i want to manage state for all 6 fields differently How can i do that ?

class Bills extends Component {
constructor(props) {
    super(props)
    this.state = {
        productName: '',
        price: 0,
        quantity: 0,
        noOfProductsField: 0
    }
}
handleChange = name => event => {
    this.setState({
        [name]: event.target.value,
    });
};

createFields = () => {
        const { classes } = this.props;
        let children = []
        for (let i = 0; i < this.state.noOfProductsField; i++) {
            children.push(
                <div>
                    <Select
                        className={classes.textField}
                         value = { this.state[i] }
                    onChange={this.handleChange('productName')}
                        displayEmpty
                        SelectProps={{
                            MenuProps: {
                                className: classes.menu,
                            }
                        }}>
                        <MenuItem value="" disabled>
                            Select Product
                           </MenuItem>
                        {this.state.products.map((option, ind) => (
                            <MenuItem key={ind} value={option.productName}>
                                {option.productName}
                            </MenuItem>
                        ))}
                    </Select>
                    <TextField className={classes.textField} placeholder='Price' type='number' onChange={this.handleChange('price')} />
                    <TextField className={classes.textField} placeholder='Quantity' type='number' onChange={this.handleChange('quantity')} />
                </div>
            )
        }
        return children
    }
}

I Have this function which is creating 3 input fields in for loop

  • productName
  • price
  • quantity

For Example if loop is running 2 times it will create 6 fields like image below:

So now i want to manage state for all 6 fields differently How can i do that ?

Share Improve this question edited Nov 17, 2018 at 8:50 Tân 1 asked Nov 17, 2018 at 8:42 Huzaifa AhmedHuzaifa Ahmed 3241 gold badge4 silver badges15 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 6

You need to create dynamic form inputs right? So what you can do is you can pass the name of the product to you handler this.handleChange('productName') and then you can do something like following. In your case you will need to use computed property name so as to dynamically set the state(like you are already doing)

handleChange = name => event => {
    //more logic here as per the requirement
    this.setState({
        [name]: event.target.value,
    });
};

Or you can create seperate onChange handlers each for product, price, quantity.

handleProductChange = (name) => (evt) => {
    const newProducts = this.state.products.map((product, pidx) => {
      if (name !== product.productName) return product;
      return { ...product, productName: evt.target.value };
    });

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

Quick flow: When product onChange occurrs you can store the product in the procucts array(in state) and when price change will occure you can send the product name along with it and map the product with price and quantity.

Here you can find a nice JS bin replica with React, of exact same thing you want to achieve.

You can add name attribute to each input component and make one handler method which get the name as an argument.

handleInputChange(event) {

  const value = event.target.value;
  const name = event.target.name;

  this.setState({
    [name]: value
  });
}

You can read more about how to handle multiple inputs on React docs.

you can create dynamic select field using react js

**Code sample:**

const templates = [
    {'id': 1, 'value': 'JavaScript', 'name': 'JavaScript'}, 
    {'id': 2, 'value': 'React', 'name': 'React'},    
    {'id': 3, 'value': 'Angular', 'name': 'Angular'},
    {'id': 4, 'value': 'Node', 'name': 'Node'},
    {'id': 5, 'value': 'Vue', 'name': 'Vue'},
 ]

class Dynamic extends React.Component {
  state={
    selectedTemplates: ""
  }

 onChange = (e) => {
   console.log(e)
   // selected value store into state
    this.setState({ 
      selectedTemplates: e.target.value 
    });
  };

  render() {
    return (
      <div>
        <h2>Dynamic Select(Options):</h2>
        <select className="form-control"
            value={this.state.value}
            onChange={(e) => this.onChange(e.target.value)}
          >
          {
              templates.map(msgTemplate => {
                  return (
                      <option 
                        key={msgTemplate.id} 
                        name={msgTemplate.name} 
                        value={msgTemplate.text}
                       >
                          {msgTemplate.name}
                      </option>
                  )
              })
          }
       </select>
     </div>
    )
  }
}

React.render(<Dynamic />, document.getElementById('app'));

demo >> codepen

Simple example for the state variables looks like:

this.state = {
test: 'hello'
}

you can get the state values dynamically by

let field_name = 'test';
let data = this.state[field_name];

you can set the state or replace the state like

let field_name = 'test';
this.setState({[field_name]: 'new'}) // test: 'new'

complex state replace like

let field_names = {key: 'test'}
this.setState({[field_name.key]: 'ok'}) // test: 'ok'
console.log(this.state[field_name.key]) // test: 'ok'

You can also use the Template literals like

this.setState({`${field_name.key}`: 'ok'}) // test: 'ok'
console.log(this.state[`${field_name.key}`]) // test: 'ok'

Superb, you got the solution.

发布评论

评论列表(0)

  1. 暂无评论