我应该如何管理在 React JS 中动态添加的多个选择字段?

如何解决我应该如何管理在 React JS 中动态添加的多个选择字段?

代码使用 react 添加动态输入字段。 两个选择下拉菜单一个输入文本。 单击添加按钮时。在旧输入块下方添加了这 3 个输入字段的相同副本。 当我更改选定的值时,它会自动更改其他选择的输入值。例如,您选择珠宝类型作为戒指,则另一种类型的珠宝也得到了体现。我是 React 的初学者。

        import React,{useState } from 'react'
        import Grid from '@material-ui/core/Grid';
        import TextField from '@material-ui/core/TextField';
        import MenuItem from '@material-ui/core/MenuItem';
        import FormControl from '@material-ui/core/FormControl';
        import InputLabel from '@material-ui/core/InputLabel';
        import Select from '@material-ui/core/Select';
        import { makeStyles } from "@material-ui/core/styles";
        import  Button  from '@material-ui/core/Button';
        const backgroundShape = require('./images/background.svg');

        const useStyles = makeStyles(theme => ({
          root: {
            flexGrow: 1,backgroundColor: '#064771',overflow: 'hidden',background: `url(${backgroundShape}) repeat`,backgroundSize: 'cover',backgroundPosition: '0 1000px',paddingBottom: 500
          },action_btn:{
            marginTop:'10px',marginRight: "5px"
          },main_grid:{
            backgroundColor: '#fff',alignItems: 'center',justifyContent: 'center',margin:'auto',display: 'flex',}
        }));

        function App() {
          const classes = useStyles();

          //handle mmultiple input
          const [state,setState] = React.useState({
            gold_caratage: "",gold_type: ""  
          });
          
        // handle input change
        const handleInputChange = (evt) => {
          const value = evt.target.value;
        setState({
          ...state,[evt.target.name]: value 
        });
        };

          //clone form logic
          const [inputList,setInputList] = useState([{ jwellary_type: "",net_gram: "",caratage:"" }]);

          //remove and add btn logic 
         const handleRemoveClick = index => {
          const list = [...inputList];
          list.splice(index,1);
          setInputList(list);
        };


         
        // handle click event of the Add button
        const handleAddClick = () => {
          setInputList([...inputList,{ jwellary_type: "",caratage:"" }]);
        };

          return (
            <div className={classes.root}>
              <typography guttorbuttom align="center">
                <h1>React Calc</h1>
              </typography>
            
              {inputList.map((x,i) => {
                return (
                  <Grid container className={classes.main_grid} spacing={3}>
                  <Grid item xs={10} sm={2}>
                  <FormControl style={{ minWidth:140 }}>
                    <InputLabel id="demo-simple-select-label">Type Of Jwellary</InputLabel>
                    <Select
                      name="gold_type"
                      value={state.gold_type}
                      onChange={handleInputChange}
                    >
                      <MenuItem value={1}>Ring</MenuItem>
                      <MenuItem value={2}>Chain</MenuItem>
                      <MenuItem value={3}>Other</MenuItem>
                    </Select>
                  </FormControl>
                </Grid>
                <Grid item xs={10} sm={2}>
                  <TextField
                     name="Net Gram"
                    label="Net Gram"
                    type="number" 
                    fullwidth
                  />
                </Grid>
                <Grid item xs={10} sm={2}>
                  <FormControl style={{ minWidth: 120 }}>
                    <InputLabel id="demo-simple-select-label">Caratage</InputLabel>
                    <Select
                       value={state.gold_caratage}
                      onChange={handleInputChange}
                      name="gold_caratage"
                    >
                      <MenuItem value={1}>22</MenuItem>
                      <MenuItem value={2}>23</MenuItem>
                      <MenuItem value={3}>24</MenuItem>
                    </Select>
                  </FormControl>
                </Grid>
                <Grid item xs={10} sm={2}>
                  <Button 
                    variant="contained" 
                    color="secondary" 
                    className={classes.action_btn}
                    onClick={() => handleRemoveClick(i)}>
                    Remove
                   </Button> 
                   <Button 
                      variant="contained" 
                      color="primary" 
                      className={classes.action_btn}
                      onClick={handleAddClick}>
                    Add
                   </Button> 
                </Grid> 
                </Grid>  
                );
              })} 
                

            </div>
          )
        }

        export default App;

解决方法

问题

这里的主要问题是您有一个用于所有输入值的状态,除了索引之外,无法区分一组输入和下一组输入。

解决方案

inputList 添加新输入集时,您需要为每个集分配唯一的 id 属性。这有几个目的:

  1. id 可用作每个映射输入集的 React 键。这有助于在删除输入集时重新呈现和协调。
  2. 您可以使用 id 更新和删除状态。

不需要单独输入 state 状态,inputList 状态具有所有必需的数据。

import { v4 as uuidV4 } from 'uuid';

export default function App() {
  const classes = useStyles();

  //clone form logic
  const [inputList,setInputList] = useState([
    {
      id: uuidV4(),// <-- provide id
      jwellary_type: "",net_gram: "",caratage: ""
    }
  ]);

  // handle input change
  const handleInputChange = (id) => (evt) => {
    const { value } = evt.target;
    setInputList((list) =>
      list.map((el) =>                 // <-- shallow copy array
        el.id === id                   // <-- match by id
          ? {
              ...el,// <-- shallow copy element
              [evt.target.name]: value // <-- update key/value
            }
          : el                         // <-- or return current element
      )
    );
  };

  //remove and add btn logic
  const handleRemoveClick = (id) => {
    // <-- shallow copy array and remove elements with mismatch id
    setInputList((list) => list.filter((el) => el.id !== id));
  };

  // handle click event of the Add button
  const handleAddClick = () => {
    setInputList([
      ...inputList,{
        id: uuidV4(),// <-- provide id
        jwellary_type: "",caratage: ""
      }
    ]);
  };

  return (
    <div className={classes.root}>
      <typography guttorbuttom align="center">
        <h1>React Calc</h1>
      </typography>

      {inputList.map((x,i) => {
        return (
          <Grid
            key={x.id} // <-- provide id as React key
            container
            className={classes.main_grid}
            spacing={3}
          >
            <Grid item xs={10} sm={2}>
              <FormControl style={{ minWidth: 140 }}>
                <InputLabel id="demo-simple-select-label">
                  Type Of Jwellary
                </InputLabel>
                <Select
                  name="jwellary_type" // <-- name to match property
                  value={x.jwellary_type} // <-- current property
                  onChange={handleInputChange(x.id)} // <-- pass id
                >
                  <MenuItem value={1}>Ring</MenuItem>
                  <MenuItem value={2}>Chain</MenuItem>
                  <MenuItem value={3}>Other</MenuItem>
                </Select>
              </FormControl>
            </Grid>
            <Grid item xs={10} sm={2}>
              <TextField
                name="Net Gram"
                label="Net Gram"
                type="number"
                fullwidth
              />
            </Grid>
            <Grid item xs={10} sm={2}>
              <FormControl style={{ minWidth: 120 }}>
                <InputLabel id="demo-simple-select-label">Caratage</InputLabel>
                <Select
                  value={x.caratage} // <-- current property
                  onChange={handleInputChange(x.id)} // <-- pass id
                  name="caratage" // <-- name to match property
                >
                  <MenuItem value={1}>22</MenuItem>
                  <MenuItem value={2}>23</MenuItem>
                  <MenuItem value={3}>24</MenuItem>
                </Select>
              </FormControl>
            </Grid>
            <Grid item xs={10} sm={2}>
              <Button
                variant="contained"
                color="secondary"
                className={classes.action_btn}
                onClick={() => handleRemoveClick(x.id)} // <-- pass id
              >
                Remove
              </Button>
              <Button
                variant="contained"
                color="primary"
                className={classes.action_btn}
                onClick={handleAddClick}
              >
                Add
              </Button>
            </Grid>
          </Grid>
        );
      })}
    </div>
  );
}

Edit how-should-i-manage-multiple-select-fields-dynamically-added-in-react-js

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?