我是ReactJ的新手,我正在尝试从输入中读取数据。问题是当我键入一个符号时,输入放宽了焦点。但是,只有当所有逻辑都在内部函数内部时。当使用按钮输入和逻辑在不同的文件中 - 它正在工作。我真的不知道为什么...
我已经创建了具有相同代码的单独文件并将其导入到索尔特 - 没关系。我已经尝试使用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>
)}
SearchComponent
是功能组件,不应在另一个组件内定义。在MyInput
内定义SearchComponent
将导致SearchComponent
重新创建(未录制(,从本质上讲,它将被删除,然后在每次点击时添加。
该解决方案非常简单,从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>
我也是新手反应重新渲染..
如果您使用 SearchComponent
作为变量,而不是匿名函数,则可以按预期工作。
我也很好奇为什么使用这样的嵌套函数(当使用JSX时(会导致这种行为...可能是抗模式?
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>
即使将嵌套函数更改为"实际组件",每个按键之后却丢失了焦点(又称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
钩子不是"挂钩"到您的SearchComponent
,而是您的MyInput
组件。每当您调用updateCitySearch()
时,您都会更改MyInput
的状态,从而将 thote 组件强制重新渲染。
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组件重新订阅和SearchComponent
都会重新创建。每次都会渲染myInput
的新迭代,并创建一个新的SearchComponent
。
但是,如果您要在SearchComponent
内定义useState
,则在状态更改时只有SearchComponent
会重新渲染,因此将原始的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>
);
}