最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do you submit on enter key press in a Chakra-UI input? - Stack Overflow

programmeradmin0浏览0评论

I'm creating a ponent that contains an input that directs the user to a new tab upon pressing enter or clicking the search button. The search button functions correctly, however I'm having trouble getting the input to call the handleSubmit method on enter key press. As of now, pressing the enter key does nothing. How can I achieve this? code:

  const LinkCard = (props) => {
  const [searchInput, setSearchInput] = useState("");
  const handleChange = (e) => {
    setSearchInput(e.target.value);
  };
  const handleClick = (e) => {
    e.preventDefault();
    location.assign(";);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    location.assign(";);
  };

  return (
    <Flex borderWidth="1px" borderRadius="lg" alignItems="center">
      {props.icon}
      <Box>{props.websiteName}</Box>
      <InputGroup>
        <Input
          placeholder={"Search " + props.websiteName}
          onChange={handleChange}
          onSubmit={handleSubmit}
          flexGrow="1"
          m="2%"
        />
        <Link href={props.url} passHref={true}>
          <a>
            <InputRightElement m="2%">
              <Button onClick={handleClick}>
                <FaSearch />
              </Button>
            </InputRightElement>
          </a>
        </Link>
      </InputGroup>
    </Flex>
  );
};

I'm creating a ponent that contains an input that directs the user to a new tab upon pressing enter or clicking the search button. The search button functions correctly, however I'm having trouble getting the input to call the handleSubmit method on enter key press. As of now, pressing the enter key does nothing. How can I achieve this? code:

  const LinkCard = (props) => {
  const [searchInput, setSearchInput] = useState("");
  const handleChange = (e) => {
    setSearchInput(e.target.value);
  };
  const handleClick = (e) => {
    e.preventDefault();
    location.assign("http://www.mozilla");
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    location.assign("http://www.mozilla");
  };

  return (
    <Flex borderWidth="1px" borderRadius="lg" alignItems="center">
      {props.icon}
      <Box>{props.websiteName}</Box>
      <InputGroup>
        <Input
          placeholder={"Search " + props.websiteName}
          onChange={handleChange}
          onSubmit={handleSubmit}
          flexGrow="1"
          m="2%"
        />
        <Link href={props.url} passHref={true}>
          <a>
            <InputRightElement m="2%">
              <Button onClick={handleClick}>
                <FaSearch />
              </Button>
            </InputRightElement>
          </a>
        </Link>
      </InputGroup>
    </Flex>
  );
};
Share Improve this question asked Aug 30, 2021 at 6:14 JacobDClarkJacobDClark 771 gold badge1 silver badge6 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5
const [value, setValue] = React.useState('');
return (
<form
  onSubmit={e=> {
    e.preventDefault();
    location.assign('?wd=' + value)
  }}>
  <input value={value} onChange={(e)=> setValue(e.currentTarget.value)} />
  <button type="submit">Search</button>
</form>
)

or

const [value, setValue] = React.useState('');

return (
<>
  <input 
     value={value} 
     onChange={(e)=> setValue(e.currentTarget.value)} 
     onKeyPress={e=> {
        if (e.key === 'Enter') {
           location.assign('?wd=' + value)
        }
     }}
  />
  <button onClick={()=> location.assign('?wd=' + value)}>Search</button>
</>
);

There are 2 possible ways you can achieve that:

  • Add a key listener on your submitHandler:
const handleSubmit = e => {
  e.preventDefault();
  if (e.key === "Enter") {
    location.assign("http://www.mozilla");
  }
};
  • Having a form around your input and add submit an event:
<form onSubmit={handleSubmit}>
  <Input
    placeholder={"Search " + props.websiteName}
    onChange={handleChange}
    onSubmit={handleSubmit}
    flexGrow="1"
    m="2%"
  />
</form>;

Typescript Answer

I found this was a mon enough problem to create a few util helper functions for:

import {KeyboardEvent} from "react"

export function handleEnterKeyPress<T = Element>(f: () => void){
    return handleKeyPress<T>(f, "Enter")
}

function handleKeyPress<T = Element>(f: () => void, key: string){
    return (e: KeyboardEvent<T>) => {
        if(e.key === key){
            f()
        }
    }
}

The functions are "higher order" in the sense that they lift a regular, zero argument void function up and give you back a nicely typed event handler that can be passed straight into the onKeyDown method.

Sample code:

<Input {...props} onKeyDown={handleEnterKeyPress(myFunction)}/>

Where myFunction is any void function you'd like to run whenever the enter key is pressed.

Note: You should use onKeyDown rather than onKeyPress as the latter is deprecated.

Update

If you want to handle multiple keys, I've found a slightly more flexible version of the above to be helpful:

import {KeyboardEvent} from "react"

export function handleEnterKeyPress<T = Element>(f: () => void){
    return handleKeyPress<T>({Enter: f})
}

export type KeyPressMap = {
    [key: string]: () => void
}

export function handleKeyPress<T = Element>(map: KeyPressMap){
    return (e: KeyboardEvent<T>) => {        
        const handler = map[e.key]
        if(handler !== undefined){
            handler()
        }
    }
}

Then in your ponent, you can call it with something like this for example, where handleEnter and handleEscape are assumed to be some functions accessible to your ponent:

const keyPressHandlers = {
    Enter: handleEnter,
    Escape: handleEscape
}

return <Input onKeyDown={handleKeyPress(keyPressHandlers)}/>
发布评论

评论列表(0)

  1. 暂无评论