Search code examples
javascriptreactjsreactstrap

How do I add multiple values to a dynamic table in react?


I have a table that gathers user input from two selects. When the user selects a field, i have successfully made it so that their input is shown on a table row, and any new input triggers a new row.

However I am having great difficulty in making it so that it displays multiple values instead of one. This is what it currently looks like:

enter image description here

Where it says the input example 'P2P2' it should only say 'P2'; everytime a new row is added the 'P2' is successfully added but it always builds up on top of each other unlike the 'Amazon' input like this: enter image description here

I know i am doing something wrong and have tried multiple methods but I dont actually know what the issue is or how to resolve the issue. Here is the code:

 
  const [shop, setShop] = useState([]);
  
  const [profil, setProfil] = useState([]);

  const [formShop, setFormShop] = useState(undefined);
  
  const [formProfil, setFormProfil] = useState(undefined);
  
  function addShop(s){
    setShop((currentShops) => [...currentShops, s]);
  }

  
  function addProfile(p){
    setProfil((currentProfiles) => [...currentProfiles, p]);
  }

  function handleSubmit(e){
    e.preventDefault();

    addShop(formShop);
    addProfile(formProfil);

  }

        ......

                    <tr>
                      {(shop.map((s) => (
                        <tr>
                        <td>{s}</td>
                        <td>{profil}</td>
                        </tr>
                      )))}
                    </tr>
                    
                    ........
                    //snippets of form select

                    <Input type="select" name="selectStore" id="selectStore" onChange={(e) => setFormShop(e.target.value)}>

                    ........

                    <Input type="select" name="selectProf" id="selectProf" onChange={(e) => setFormProfil(e.target.value)}>

                    ........



Solution

  • I suggest you to use an object to main the pair shop - profile , here is a working example.

    const {useState} = React;
    const {
      Modal,
      ModalHeader,
      ModalBody,
      ModalFooter,
      Input,
      FormGroup,
      FormText,
      Form,
      Label,
      Button,
      Card,
      CardHeader,
      CardBody,
      CardTitle,
      //CardFooter,
      Table,
      Row,
      ButtonGroup,
      Col,
    } = Reactstrap;
    
    const App = (props) => {
      const [shopProfil, setShopProfil] = useState([]);
    
    
      const [formShop, setFormShop] = useState(undefined);
    
      const [formProfil, setFormProfil] = useState(undefined);
    console.log(formShop,formProfil)
    
    
      function addShopProfil(obj) {
        setShopProfil((currentShopProfiles) => {
          const curr = currentShopProfiles.slice()
          curr.push(obj);
          return curr
        })
      }
    
      function handleSubmit(e) {
        e.preventDefault();
        const objshopProfil ={
          formshop:formShop,
          formprofil:formProfil
        };
    
        
        addShopProfil(objshopProfil);
        
      }
    
      return (
        <div>
          <div>
            <Table>
              <tbody>
                <tr>
                  {shopProfil.map((s,index) => (
                    <tr key={`${s.formshop+s.formprofil+index}`}>
                      <td>{s.formshop}</td>
                      <td>{s.formprofil}</td>
                    </tr>
                  ))}
                </tr>
              </tbody>
            </Table>
          </div>
    
          <Form onSubmit={handleSubmit}>
            <FormGroup>
              <Label for="selectStore">Store</Label>
              <Input
                type="select"
                name="selectStore"
                id="selectStore"
                onChange={(e) => setFormShop(e.target.value)}
              >
                <option>-</option>
                <option>Amazon </option>
                <option>Local</option>
                <option>Target</option>
              </Input>
            </FormGroup>
            <FormGroup>
              <Label for="selectProf">Profile</Label>
              <Input
                type="select"
                name="selectProf"
                id="selectProf"
                onChange={(e) => setFormProfil(e.target.value)}
              >
                <option>-</option>
                <option>P1</option>
                <option>P2</option>
                <option>P3</option>
                <option>P4</option>
              </Input>
            </FormGroup>
            <button type="submit">button</button>
          </Form>
        </div>
      );
    };
    
    ReactDOM.render(
      <App />,
      document.getElementById('app')
    );
    <script src="https://npmcdn.com/react@15/dist/react-with-addons.js"></script>
    <script src="https://npmcdn.com/reactstrap@3/dist/reactstrap.min.js"></script>
    <link href="https://npmcdn.com/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    
    
    <div id="app"></div>

    Or if you want to maintain the same structure look here :

    const {useState} = React;
    const {
      Modal,
      ModalHeader,
      ModalBody,
      ModalFooter,
      Input,
      FormGroup,
      FormText,
      Form,
      Label,
      Button,
      Card,
      CardHeader,
      CardBody,
      CardTitle,
      //CardFooter,
      Table,
      Row,
      ButtonGroup,
      Col,
    } = Reactstrap;
    
    const App = (props) => {
      const [shop, setShop] = useState([]);
    
      const [profil, setProfil] = useState([]);
    
      const [formShop, setFormShop] = useState(undefined);
    
      const [formProfil, setFormProfil] = useState(undefined);
    
      function addShop(s) {
        setShop((currentShops) => [...currentShops, s]);
      }
    
      function addProfile(p) {
        setProfil((currentProfiles) => [...currentProfiles, p]);
      }
    
      function handleSubmit(e) {
        e.preventDefault();
    
        addShop(formShop);
        addProfile(formProfil);
      }
    
      return (
        <div>
          <div>
            <Table>
              <tbody>
                <tr>
                  {shop.map((s,i) => (
                    <tr key={`${s+i}`}>
                      <td>{s}</td>
                      <td>{profil[i]}</td>
                    </tr>
                  ))}
                </tr>
              </tbody>
            </Table>
          </div>
    
          <Form onSubmit={handleSubmit}>
            <FormGroup>
              <Label for="selectStore">Store</Label>
              <Input
                type="select"
                name="selectStore"
                id="selectStore"
                onChange={(e) => setFormShop(e.target.value)}
              >
                <option>-</option>
                <option>Amazon </option>
                <option>Local</option>
                <option>Target</option>
              </Input>
            </FormGroup>
            <FormGroup>
              <Label for="selectProf">Profile</Label>
              <Input
                type="select"
                name="selectProf"
                id="selectProf"
                onChange={(e) => setFormProfil(e.target.value)}
              >
                <option>-</option>
                <option>P1</option>
                <option>P2</option>
                <option>P3</option>
                <option>P4</option>
              </Input>
            </FormGroup>
            <button type="submit">button</button>
          </Form>
        </div>
      );
    };
    
    ReactDOM.render(
      <App />,
      document.getElementById('app')
    );
    <script src="https://npmcdn.com/react@15/dist/react-with-addons.js"></script>
    <script src="https://npmcdn.com/reactstrap@3/dist/reactstrap.min.js"></script>
    <link href="https://npmcdn.com/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    
    
    <div id="app"></div>