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
组件)因此你失去了焦点。
在
这里我有一个令人困惑的例子,其中函数调用和标记之间的差异导致焦点行为发生变化。我确信那里有 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
组件)因此你失去了焦点。