React JSX vs 函数在焦点处理上有区别吗?

React JSX vs function there are difference in focus handling?

当涉及到函数调用或(标记)组件之间的差异时,问题得到了 'no' 的回答。

这里我有一个令人困惑的例子,其中函数调用和标记之间的差异导致焦点行为发生变化。我确信那里有 React 专家给出了合理的解释 - 不幸的是我还没有到那里 ;-)

这里的代码带有标记和函数调用之间的注释差异:


import React, {useState} from 'react';

function FocusRiddle() {

    const [currentRow, setCurrentRow] = useState({firstName: 'Barack', lastName: 'Obama'});

    // This keeps the focus correctly
    return <div>{Att()}</div>;

    // This loses the focus after every letter !!!
    // return <div><Att /></div>;

    function Att() {
        return <div>
            <h1>Welcome to Focus Riddle</h1>
            <div>
                <MyInput key={'firstName'} name={'firstName'} row={currentRow} action={updateRow}/>
            </div>
            <div>
                <MyInput key={'lastName'} name={'lastName'} row={currentRow} action={updateRow}/>
            </div>
            <div>
                <button onClick={() => alert(JSON.stringify(currentRow))}>Show Row</button>
            </div>
        </div>
    }


    function updateRow(name, value) {
        setCurrentRow({...currentRow, [name]: value});
    }

}

function MyInput({name, row, action}) {
    return <input
        value={row[name]}
        onChange={(event) => action(name, event.target.value)}/>
}

export default FocusRiddle;

调用Att()相当于实现一个普通的组件,因为你只是声明了一个函数并在组件范围内调用它。

所以这里没什么特别的,状态应该持续存在:

function FocusRiddle() {
  const [currentRow, setCurrentRow] = useState({
    firstName: "Barack",
    lastName: "Obama",
  });

  function updateRow(name, value) {
    setCurrentRow({ ...currentRow, [name]: value });
  }

  return (
    <div>
      <div>
        <h1>Welcome to Focus Riddle</h1>
        <div>
          <MyInput
            key={"firstName"}
            name={"firstName"}
            row={currentRow}
            action={updateRow}
          />
        </div>
        <div>
          <MyInput
            key={"lastName"}
            name={"lastName"}
            row={currentRow}
            action={updateRow}
          />
        </div>
        <div>
          <button onClick={() => alert(JSON.stringify(currentRow))}>
            Show Row
          </button>
        </div>
      </div>
    </div>
  );
}

但是,在调用 <Att/> 时,您创建了 React Element, because using JSX syntax is a sugar syntax for React.createElement. See JSX in depth.

所以有了它,React 元素会意识到 props 在它们的父级被渲染时发生变化和渲染

当您输入 input 并调用 setCurrentRow 时,FocusRiddle 得到呈现,并且 Att 组件 卸载 (因为你在每个渲染器上重新声明 Att 组件)因此你失去了焦点。