我的导航部件上有个搜索栏。每次击键后,输入将失去焦点,您必须重新单击它才能键入下一个键。
以下是输入:
<input
type="text"
name="search"
placeholder="Search"
value={search}
onChange={handleInputChange}
/>下面是handleInputChange函数:
function handleInputChange(event) {
event.preventDefault();
let value = event.target.value;
setSearch(value);
}下面是设置搜索的钩子:
const [search, setSearch] = useState("");我尝试在输入中添加一个键,但这不起作用。当我将搜索输入移动到一个新组件时,这也不起作用。
以下是完整的代码:
import React, { useEffect, useState, useCallback } from "react";
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import { Row, Col } from '../Grid';
import IconButton from '@material-ui/core/IconButton';
import SearchIcon from '@material-ui/icons/Search';
import ShoppingCartOutlinedIcon from '@material-ui/icons/ShoppingCartOutlined';
import MenuIcon from '@material-ui/icons/Menu';
import Badge from '@material-ui/core/Badge';
import useScrollTrigger from '@material-ui/core/useScrollTrigger';
import Slide from '@material-ui/core/Slide';
import SideMenu from '../SideMenu';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import { toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { css } from 'glamor';
import "./style.css";
function Navbar(props) {
const cart = useSelector(state => state.cart);
const [cartTotal, setCartTotal] = useState(0);
const [loggedIn, setLoggedIn] = useState(false);
const [search, setSearch] = useState("");
const [isOpen, setIsOpen] = useState(false);
const [renderMiddleCol, setMiddleCol] = useState(true);
const [menuClass, setMenuClass] = useState("no-menu");
useEffect(() => {
if (cart[0]) {
setCartTotal(cart[0].line_items.length)
}
}, [cart[0]]);
useEffect(() => {
if (window.sessionStorage.id) {
setLoggedIn(true);
} else {
setLoggedIn(false);
}
}, [loggedIn]);
useEffect(() => {
if (window.innerWidth < 450) {
setMiddleCol(false);
} else {
setMiddleCol(true);
}
}, [window.innerWidth]);
function HideOnScroll(props) {
const { children, window } = props;
const trigger = useScrollTrigger({ target: window ? window() : undefined });
return (
<Slide appear={false} direction="down" in={!trigger}>
{children}
</Slide>
);
}
HideOnScroll.propTypes = {
children: PropTypes.element.isRequired,
window: PropTypes.func,
};
function CheckCart() {
if (window.sessionStorage.id) {
window.location.href = "/cart";
} else {
toast("Please login to view your cart", {
className: css({
background: '#3E0768',
boxShadow: '2px 2px 20px 2px rgba(0,0,0,0.3)',
borderRadius: '17px'
}),
bodyClassName: css({
fontSize: '20px',
color: 'white'
}),
progressClassName: css({
background: "linear-gradient(90deg, rgba(0,0,0,1) 0%, rgba(62,7,104,1) 80%)"
})
});
}
}
function Search() {
if (search) {
sessionStorage.setItem("search", search);
window.location.href = "/search";
} else {
toast("Search field cannot be empty", {
className: css({
background: '#3E0768',
boxShadow: '2px 2px 20px 2px rgba(0,0,0,0.3)',
borderRadius: '17px'
}),
bodyClassName: css({
fontSize: '20px',
color: 'white'
}),
progressClassName: css({
background: "linear-gradient(90deg, rgba(0,0,0,1) 0%, rgba(62,7,104,1) 80%)"
})
});
}
}
function logOut(event) {
event.preventDefault();
setIsOpen(false);
sessionStorage.clear();
window.location.href = "/login";
}
function handleInputChange(event) {
event.preventDefault();
let value = event.target.value;
setSearch(value);
}
function toggleMenu(event) {
event.preventDefault();
setIsOpen(!isOpen);
if (menuClass === "no-menu") {
setMenuClass("menu-background");
} else {
setMenuClass("no-menu");
}
}
const theme = createMuiTheme({
palette: {
primary: {
main: '#000000',
contrastText: '#ffffff',
},
secondary: {
light: '#3E0768',
main: '#3E0768',
contrastText: '#ffffff',
},
tertiary: {
main: '#ffffff',
}
},
});
return (
<MuiThemeProvider theme={theme}>
<HideOnScroll {...props}>
<AppBar position="fixed" color="primary">
<Toolbar>
<Col size="md-1">
<IconButton
onClick={toggleMenu}
aria-label="Menu"
>
<MenuIcon
fontSize="large"
className="white"
/>
</IconButton>
</Col>
<Col size="md-2">
<a href="/" className="white "><h6>Demo Company</h6></a>
</Col>
{renderMiddleCol ? (
<Col size="lg-6 md-5 sm-3" />
) : (<div />)}
<Col size="md-2 4">
<Row no-gutters>
<div className="search-box">
<Col size="md-2 1">
<IconButton onClick={Search} aria-label="search" >
<SearchIcon className="white" />
</IconButton>
</Col>
<Col size="md-8 9">
{/* <SearchForm
value={search}
onChange={handleInputChange}
/> */}
<input
className="search-field white"
type="text"
name="search"
placeholder="Search"
value={search}
onChange={handleInputChange}
/>
</Col>
</div>
</Row>
</Col>
<Col size="md-1">
<IconButton
onClick={CheckCart}
aria-label="Go to cart"
>
<MuiThemeProvider theme={theme}>
<Badge
badgeContent={cartTotal}
color="secondary"
>
<ShoppingCartOutlinedIcon className="white" />
</Badge>
</MuiThemeProvider>
</IconButton>
</Col>
</Toolbar>
</AppBar>
</HideOnScroll>
<SideMenu
isOpen={isOpen}
menuClass={menuClass}
toggleMenu={toggleMenu}
loggedIn={loggedIn}
logOut={logOut}
/>
</MuiThemeProvider>
);
}
export default Navbar;发布于 2019-12-06 21:26:07
最后,我在输入上使用了一个ref,并将它的焦点设置在每个重呈现上。这是修复它的代码。
const [search, setSearch] = useState("");
const searchInput = React.useRef(null);
useEffect(() => {
searchInput.current.focus();
}, [search]);以下是输入:
<input
ref={searchInput}
className="search-field white"
type="text"
name="search"
placeholder="Search"
value={search}
onChange={handleInputChange}
/>解决方案的功劳:React: set focus on componentDidMount, how to do it with hooks?
发布于 2019-12-05 19:03:55
下面是我发现有帮助的详细解释:https://reactkungfu.com/2015/09/react-js-loses-input-focus-on-typing/
总结一下:如果没有一个不变的键,React就是在状态改变时丢弃您控制的输入的先前实例,并在其位置上创建一个新的实例。有焦点的输入在其值更改后立即被移除。
确保:
key属性key的值不是以任何方式从输入的value派生的,因为您不希望在值更改时更改键
发布于 2020-01-03 11:48:59
我不知道具体原因,但我的焦点问题通过更改代码解决了:
import { Route } from 'react-router-dom'
<Route path='xxx' component={() => <TheComponent... />}其中,TheComponent包含输入元素,该元素在键入时失去焦点,对应于以下代码:
<Route path='xxx'>
<TheComponent... />
</Route>看看my SO question,希望有人很快就能了解到这是怎么回事
https://stackoverflow.com/questions/59199797
复制相似问题