输入正在失去对挂钩更新的关注
Input is loosing focus on hooks update
我是 reactjs 的新手,我正在尝试从输入中读取数据。问题是当我输入一个符号时,我的输入失去了焦点。但只有当所有逻辑都在函数内部时。
当带按钮的输入和逻辑在不同的文件中时 - 它正在工作。我真的不知道为什么...
我已经用相同的代码创建了单独的文件并将其导入到解决方案中 - 没关系。
我试过 onChange={handleChange} - 也失去了焦点。
export default function MyInput(){
const [citySearch, updateCitySearch] = useState();
function searchCityClick(){
alert(citySearch);
}
const SearchComponent = ()=> (
<div>
<input
value={citySearch}
onChange={(e) => updateCitySearch(e.target.value)}/>
<Button variant="contained" color="primary" onClick={searchCityClick}>
Search
</Button>
</div>
);
return(
<div>
<div>
<SearchComponent />
</div>
</div>
)}
我也是 React 的新手,所以请对我的解释持保留态度(希望其他人可以详细说明)。我相信它与嵌套组件以及 React 的方式有关 re-rendering。 .
如果您使用 SearchComponent
作为变量而不是匿名函数,这将按预期工作。
我也很好奇为什么使用这样的嵌套函数(当使用 JSX 时)会导致这种行为......可能是 anti-pattern?
function MyInput() {
const [citySearch, updateCitySearch] = React.useState();
function searchCityClick() {
alert(citySearch);
}
const SearchComponent = (
<div>
<input
value={citySearch}
onChange={(e) => updateCitySearch(e.target.value)}/>
<button variant="contained" color="primary" onClick={searchCityClick}>
Search
</button>
</div>
);
return (
<div>
<div>
{SearchComponent}
</div>
</div>
);
}
let div = document.createElement("div");
div.setAttribute("id", "app");
document.body.append(div);
ReactDOM.render(<MyInput />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
即使您将嵌套函数更改为 "actual component",每次按键后焦点都会丢失(又名 onChange)..
无效:
function MyInput() {
const [citySearch, updateCitySearch] = React.useState();
function searchCityClick() {
alert(citySearch);
}
const SearchComponent = () => {
return (
<div>
<input
value={citySearch}
onChange={(e) => updateCitySearch(e.target.value)}/>
<button variant="contained" color="primary" onClick={searchCityClick}>
Search
</button>
</div>
);
}
return (
<div>
<div>
<SearchComponent />
</div>
</div>
);
}
发生这种情况是因为 useState
挂钩不是 "hooked" 您的 SearchComponent
,而是您的 MyInput
组件。无论何时,您调用 updateCitySearch()
都会更改 MyInput
的状态,从而迫使 整个 组件变为 re-render。
SearchComponent
,在MyInput
中明确定义。当 citySearch-state
更新时,SearchComponent
失去焦点,因为它周围的初始 virual DOM
不再完整,取而代之的是一个全新的 DOM。本质上,每次 MyInput
按状态更新时,您都在创建一个全新的 SearchComponent
。
考虑以下示例:
function App() {
const [citySearch, updateCitySearch] = useState("");
console.log("rendered App again"); //always prints
const SearchComponent = () => {
console.log("rendered Search"); //always prints
const searchCityClick = () => {
alert(citySearch);
};
return (
<div>
<input
value={citySearch}
onChange={e => {
updateCitySearch(e.target.value);
}}
/>
<button onClick={searchCityClick}>Search</button>
</div>
);
};
return (
<div>
<div>
<SearchComponent />
</div>
</div>
);
}
每次更新状态时,都会触发 console.log()
,App 组件 re-render 和 SearchComponent
获取 re-created。每次都会渲染 myInput
的新迭代并创建新的 SearchComponent
。
但是如果你要在 SearchComponent
中定义 useState
,那么只有 SearchComponent
会 re-render 状态改变,从而留下原来的 myInput
组件不变,当前SearchComponent
完好无损。
function App() {
console.log("rendered App again"); //would never print a 2nd time.
const SearchComponent = () => {
const [citySearch, updateCitySearch] = useState("");
console.log("rendered Search"); //would print with new state change
const searchCityClick = () => {
alert(citySearch);
};
return (
<div>
<input
value={citySearch}
onChange={e => {
updateCitySearch(e.target.value);
}}
/>
<button onClick={searchCityClick}>Search</button>
</div>
);
};
return (
<div>
<div>
<SearchComponent />
</div>
</div>
);
}
SearchComponent
是功能组件,不应在另一个组件内定义。在 MyInput
内定义 SearchComponent
将导致重新创建 SearchComponent
(而不是重新呈现),本质上它的 DOM 将被删除,然后在每次点击时重新添加。
解决方案非常简单,从 MyInput
中提取 SearchComponent
,然后通过 props
对象传递函数和数据:
const { useState, useCallback } = React;
const SearchComponent = ({ citySearch, updateCitySearch, searchCityClick }) => (
<div>
<input
value={citySearch}
onChange={e => updateCitySearch(e.target.value)} />
<button onClick={searchCityClick}>Search</button>
</div>
);
const MyInput = () => {
const [citySearch, updateCitySearch] = useState('');
const searchCityClick = () => alert(citySearch);
return(
<div>
<SearchComponent
citySearch={citySearch}
updateCitySearch={updateCitySearch}
searchCityClick={searchCityClick} />
</div>
);
};
ReactDOM.render(
<MyInput />,
root
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
我是 reactjs 的新手,我正在尝试从输入中读取数据。问题是当我输入一个符号时,我的输入失去了焦点。但只有当所有逻辑都在函数内部时。 当带按钮的输入和逻辑在不同的文件中时 - 它正在工作。我真的不知道为什么...
我已经用相同的代码创建了单独的文件并将其导入到解决方案中 - 没关系。 我试过 onChange={handleChange} - 也失去了焦点。
export default function MyInput(){
const [citySearch, updateCitySearch] = useState();
function searchCityClick(){
alert(citySearch);
}
const SearchComponent = ()=> (
<div>
<input
value={citySearch}
onChange={(e) => updateCitySearch(e.target.value)}/>
<Button variant="contained" color="primary" onClick={searchCityClick}>
Search
</Button>
</div>
);
return(
<div>
<div>
<SearchComponent />
</div>
</div>
)}
我也是 React 的新手,所以请对我的解释持保留态度(希望其他人可以详细说明)。我相信它与嵌套组件以及 React 的方式有关 re-rendering。 .
如果您使用 SearchComponent
作为变量而不是匿名函数,这将按预期工作。
我也很好奇为什么使用这样的嵌套函数(当使用 JSX 时)会导致这种行为......可能是 anti-pattern?
function MyInput() {
const [citySearch, updateCitySearch] = React.useState();
function searchCityClick() {
alert(citySearch);
}
const SearchComponent = (
<div>
<input
value={citySearch}
onChange={(e) => updateCitySearch(e.target.value)}/>
<button variant="contained" color="primary" onClick={searchCityClick}>
Search
</button>
</div>
);
return (
<div>
<div>
{SearchComponent}
</div>
</div>
);
}
let div = document.createElement("div");
div.setAttribute("id", "app");
document.body.append(div);
ReactDOM.render(<MyInput />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
即使您将嵌套函数更改为 "actual component",每次按键后焦点都会丢失(又名 onChange)..
无效:
function MyInput() {
const [citySearch, updateCitySearch] = React.useState();
function searchCityClick() {
alert(citySearch);
}
const SearchComponent = () => {
return (
<div>
<input
value={citySearch}
onChange={(e) => updateCitySearch(e.target.value)}/>
<button variant="contained" color="primary" onClick={searchCityClick}>
Search
</button>
</div>
);
}
return (
<div>
<div>
<SearchComponent />
</div>
</div>
);
}
发生这种情况是因为 useState
挂钩不是 "hooked" 您的 SearchComponent
,而是您的 MyInput
组件。无论何时,您调用 updateCitySearch()
都会更改 MyInput
的状态,从而迫使 整个 组件变为 re-render。
SearchComponent
,在MyInput
中明确定义。当 citySearch-state
更新时,SearchComponent
失去焦点,因为它周围的初始 virual DOM
不再完整,取而代之的是一个全新的 DOM。本质上,每次 MyInput
按状态更新时,您都在创建一个全新的 SearchComponent
。
考虑以下示例:
function App() {
const [citySearch, updateCitySearch] = useState("");
console.log("rendered App again"); //always prints
const SearchComponent = () => {
console.log("rendered Search"); //always prints
const searchCityClick = () => {
alert(citySearch);
};
return (
<div>
<input
value={citySearch}
onChange={e => {
updateCitySearch(e.target.value);
}}
/>
<button onClick={searchCityClick}>Search</button>
</div>
);
};
return (
<div>
<div>
<SearchComponent />
</div>
</div>
);
}
每次更新状态时,都会触发 console.log()
,App 组件 re-render 和 SearchComponent
获取 re-created。每次都会渲染 myInput
的新迭代并创建新的 SearchComponent
。
但是如果你要在 SearchComponent
中定义 useState
,那么只有 SearchComponent
会 re-render 状态改变,从而留下原来的 myInput
组件不变,当前SearchComponent
完好无损。
function App() {
console.log("rendered App again"); //would never print a 2nd time.
const SearchComponent = () => {
const [citySearch, updateCitySearch] = useState("");
console.log("rendered Search"); //would print with new state change
const searchCityClick = () => {
alert(citySearch);
};
return (
<div>
<input
value={citySearch}
onChange={e => {
updateCitySearch(e.target.value);
}}
/>
<button onClick={searchCityClick}>Search</button>
</div>
);
};
return (
<div>
<div>
<SearchComponent />
</div>
</div>
);
}
SearchComponent
是功能组件,不应在另一个组件内定义。在 MyInput
内定义 SearchComponent
将导致重新创建 SearchComponent
(而不是重新呈现),本质上它的 DOM 将被删除,然后在每次点击时重新添加。
解决方案非常简单,从 MyInput
中提取 SearchComponent
,然后通过 props
对象传递函数和数据:
const { useState, useCallback } = React;
const SearchComponent = ({ citySearch, updateCitySearch, searchCityClick }) => (
<div>
<input
value={citySearch}
onChange={e => updateCitySearch(e.target.value)} />
<button onClick={searchCityClick}>Search</button>
</div>
);
const MyInput = () => {
const [citySearch, updateCitySearch] = useState('');
const searchCityClick = () => alert(citySearch);
return(
<div>
<SearchComponent
citySearch={citySearch}
updateCitySearch={updateCitySearch}
searchCityClick={searchCityClick} />
</div>
);
};
ReactDOM.render(
<MyInput />,
root
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>