反应-表行中的输入失去了对输入的关注

时间:2020-09-17 05:43:59

标签: reactjs react-hooks react-functional-component

我正在对表系统进行重构,以容纳动态组件而不只是文本。我已经解决了旧表系统中所有问题,除了一个。我在表格行中有一个输入框,用于更新数据库中的翻译。基本上,每次您在输入框中键入内容时,输入内容都会在一个字母后失去焦点。看来整棵树都在退缩。我在map方法中创建的每一行上都有一个键集。我尝试了所有我能想到的东西。我尝试一次将键附加到一个元素,混合元素,整个树,所有这些都使用静态element_UUID,并且UUID是我们的SQL id UUID,在渲染时不会更改。我还尝试过将名称和ID属性添加到混合中/全部使用。我尝试过将不同的功能移到不同的地方。我也尝试在多个组件上使用React.memo。我认为我可能会丢失一些有关按键如何工作的信息。我已附上一个示例代码笔。我已经将其缩小为表结构中的核心问题。

const startingRows = [
  {
    id: "53b8f2f2-d4ef-4e99-a8bb-bd82c6186e4f",
    key: "login",
    value: "connexion"
  },
  {
    id: "562295c5-be86-4d03-b31f-89127346096d",
    key: "name",
    value: "nom"
  },
  {
    id: "5d3b7d33-bf74-4ea2-ab15-3220ebe9d9e9",
    key: "password",
    value: null
  }
];

const useForm = () => {
  const [inputs, setInputs] = React.useState({});

  const handleInputChange = (e) => {
    e.persist();
    setInputs((inputs) => ({
      ...inputs,
      [e.target.name]: e.target.value
    }));
  };

  return {
    handleInputChange,
    inputs
  };
};

const Show = () => {
  const { inputs, handleInputChange } = useForm();
 
  const tableProps = {
    // Passing in the root components high level state that's required in the TableRows
    TableRow: TableRow({
      inputs,
      handleInputChange
    }),
    rows: { count: 3, records: startingRows }
  };

  return <Table {...tableProps} />;
};

const Table = ({ TableRow, rows: { count, records } }) => {
  return <TableContent TableRow={TableRow} rows={records} />;
};


// It's my understanding that the key below
// attached to the TableRow in the map method
// is what allows React to differeniate between
// what needs to be updated and what doesn't
const TableContent = ({ TableRow, rows }) => {
  return (
    <table>
      <thead>
        <tr>
          <th>Word</th>
          <th>Translation</th>
        </tr>
      </thead>
      <tbody>
        {rows && rows.map((row) => <TableRow key={row.id} row={row} />)}
      </tbody>
    </table>
  );
};

const TableRow = ({ handleInputChange, inputs }) => ({
  // key in this sense means a locale key
  row: { id, key, value }
}) => {
  return (
    <tr>
      <td>{key}</td>
      <td>
        <Input
          name={id}
          onChange={handleInputChange}
          value={inputs[id] || value}
        />
      </td>
    </tr>
  );
};

const Input = ({ id, name, onChange, value }) => {
  return <input name={name} onChange={onChange} value={value} />;
};

ReactDOM.render(<Show />, document.getElementById("root"));
body {
  height: 100vh;
  margin: 0;
  display: grid;
  place-items: center;
}
.box {
  width: 300px;
  h1 {
    font-size: 20px;
    margin: 0 0 1rem 0;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.7.0-alpha.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.7.0-alpha.0/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap-sass@3.4.1/assets/javascripts/bootstrap.min.js"></script>
<div id="root"></div>

codepen

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

使用ref渲染组件时,您需要再次添加焦点,将输入组件更改为此。我试过了,这是可行的。

const Input = ({ id, name, onChange, value }) => {
     React.useEffect(()=>{
        this.nameInput.focus();
  })
  
  return <input name={name}
           ref={(input) => { this.nameInput = input; }} 
           onChange={onChange} value={value} />;
};