0

Building input elements into a table and loading the elements with data ala a CRUD grid. It was my understanding that when a react state signals a re-render of the page that all the elements are re-rendered. In my test case, I am using defaultValue to give the inputs their data value; however when the state changes (ie I reorder the array) the values do not change for the inputs.

Code SandBox TestCase

Note that when you click a Move Up Button the actual array is reordered but not reflected in the grid.

import { useState } from "react";
import "./styles.css";

export default function App() {
  const [gridData, setGridData] = useState([
    { recordid: 1, companyname: "Devshare", contactname: "Joeann Rechert" },
    { recordid: 2, companyname: "Shufflebeat", contactname: "Lazare Kubiczek" },
    { recordid: 3, companyname: "Mita", contactname: "Jordain Copyn" }
  ]);

  const moveRecordUp = (e) => {
    e = e.target || e;
    let row = parseInt(e.getAttribute("data-row"));
    let nGridData = gridData;
    let holdRow = nGridData[row];
    nGridData.splice(row, 1);
    nGridData.splice(row - 1, 0, holdRow);
    setGridData([...nGridData]);
  };

  console.log(gridData);

  return (
    <div className="App">
      {gridData.map((r, rndx) => {
        return (
          <div key={rndx} style={{ display: "flex" }}>
            <input defaultValue={r.companyname} value={r.companyname} />
            <input defaultValue={r.contactname} />
            {rndx > 0 && (
              <button data-row={rndx} onClick={moveRecordUp}>
                Move Up
              </button>
            )}
          </div>
        );
      })}
    </div>
  );
}
2
  • 1
    Please also add the relevant code here. It makes it easier for whoever looks at the question to understand what you are trying to achieve. Commented Jan 5, 2022 at 14:23
  • 1
    No problem, just seemed like a lot of code Commented Jan 5, 2022 at 14:28

2 Answers 2

2

As answered previously , the issue is occuring because you need to use the value prop in both the input elements for the changes to reflect. And for your concern of making the input editable onChange prop is required . You can try using this approach :-


  const handleChange = (e: any, rndx: number, changingVariable: string) => {
    const value = { ...gridData[rndx], [changingVariable]: e.target.value }
    const arr = [...gridData]
    arr[rndx] = value
    setGridData(arr)
  }
            <input
              defaultValue={r.companyname}
              value={r.companyname}
              onChange={(e) => {
                handleChange(e, rndx, 'companyname')
              }}
            />
            <input
              defaultValue={r.contactname}
              value={r.contactname}
              onChange={(e) => {
                handleChange(e, rndx, 'contactname')
              }}
            />
          
Sign up to request clarification or add additional context in comments.

Comments

0

The reason for your issue is that defaultValue sets only the initial value of the input. You should set the value of the input to r.companyName as well:

<input defaultValue={r.companyname} value={r.companyname}/>
<input defaultValue={r.contactname} value={r.contactname}/>

3 Comments

on the 2nd line you should have value={r.contactname}
Yes; however, I don't want the input to be controlled. Putting the "value" attribute in the input does not allow me to type in the field.
hmm.. that's interesting. You may be able to update the DOM with a useEffect because it seems like the gridData actually changes behind the scenes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.