React JSX vs function焦点处理上有区别吗?

问题描述 投票:1回答:1

React JSX vs function call to present component中当涉及到函数调用或(标签)组件之间的差异时,该问题以“否”回答。

这里有一个令人困惑的示例,其中函数调用和标记之间的差异导致焦点行为的变化。我确信那里有合理的解释的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;
javascript reactjs focus
1个回答
1
投票

调用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,因为使用JSX语法是React.createElement的糖语法。参见React.createElement

因此,React元素对道具的了解会在其父对象被渲染时改变并渲染。

当您输入JSX in depth并调用input时,将渲染setCurrentRow,并且FocusRiddle组件unmounts(因为在每个渲染中都重新声明了Att组件),因此您失去了焦点。

© www.soinside.com 2019 - 2024. All rights reserved.