将表情符号添加到输入

Add emojis to input

我正在聊天,我正在使用一个名为 emoji-picker-react 的库,我想将表情符号添加到我的文本字段,然后将其作为消息发送。我正在使用 React,所以为了方便起见,我将简化代码。 我的消息有效,但我的表情符号没那么多。 到目前为止,如果我先单击表情符号然后再单击一些文本,就可以了。 但如果我先打字,然后尝试添加表情符号,那将无法正常工作。 另外,如果我尝试自己发送表情符号,它也不会起作用。 这就是我用来在我的文本字段中添加表情符号的方法,两者都做同样的事情。

这是我尝试将表情符号添加到我的文本字段中的地方,并且正在执行我刚刚解释的操作:

const onEmojiClick = (e, emojiObject) => {
document.querySelector("#text").value += emojiObject.emoji
  // document.getElementById("text").value += emojiObject.emoji
};

这是我的输入字段:

<input
 id="text"
 style={inputStyles}
 type="text"
 placeholder="Type your message"
 value={message}
 onKeyPress={e => {
  if (e.key !== 'Enter') return;
    sendMessage(message);
  }
 }
 onChange={e => setMessageForm(e.target.value)}
/>

我确信这很简单,但我无法理解它。希望有人能指导一下。

谢谢!

明确设置文本输入的 value 不会触发 onChange 事件。在保存输入状态的组件中包含表情符号选择器,并在选择表情符号时将其称为 setter(假设您使用功能组件,否则调用 this.setState),将其附加到当前状态。

您可能希望在输入元素上使用 ref 读取光标位置,并在其中插入表情符号 selectionStart 属性。

例如,您可以这样编写输入组件

import React, { useState, useRef } from 'react'
import /* your EmojiPicker component */

const InputWithEmojiPicker = () => {
  const [value, setValue] = useState('')
  const inputRef = useRef(null)
  
  const onEmojiClick = (e, emojiObject) => {
    const { selectionStart, selectionEnd } = inputRef.current
    // replace selected text with clicked emoji
    const newVal = value.slice(0, selectionStart) + emojiObject.emoji + value.slice(selectionEnd)
    setValue(newValue)
  }

  return (
    <div>
      <input type="text" ref={inputRef} value={value} onChange={setValue} />
      {/* your EmojiPicker component with onEmojiClick */}
    </div>
  )
}

export default InputWithEmojiPicker

创建对 input 节点的引用以获取光标位置并更新消息值:

  const ref = useRef(null);
  const onEmojiClick = (event, emojiObject) => {
    const cursor = ref.current.selectionStart;
    const text = message.slice(0, cursor) + emojiObject.emoji + message.slice(cursor);
    setMessageForm(text);
  };

jsx

<input
  id="text"
  ref={ref}
  ...
/>

https://stackblitz.com/edit/react-gg2akb?file=src%2FApp.js

对@lissettdm 的回答进行了一些更新。

插入表情符号时的常见问题。

插入表情符号后,光标会移动到行尾。

改进答案

光标停留在表情符号所在的位置,以便用户可以输入多个表情符号。

 const ref = useRef(null);
  const onEmojiClick = (event, emojiObject) => {
    const cursor = ref.current.selectionStart;
    
    const text = message.slice(0, cursor) + emojiObject.emoji + message.slice(cursor);
    setMessageForm(text);
    
    //Codes added for the new cursor
    const newCursor = cursor+emojiObject.emoji.length
    setTimeout(() => ref.current.setSelectionRange(newCursor,newCursor), 10)
  };

代码解释

根据您使用的表情包,emojiObject.emoji可能是统一的、原生的或id。 常见错误和最大错误是假设1个表情符号= 1个字符(光标+1),事实并非如此。

例如,如果您正在使用 emoji-mart,并且您使用 emoji.native,则长度为 2(而不是 1)。

const newCursor = cusor+emojiObject.emoji.length

以下将新的光标位置设置在表情符号之后。为什么超时?这是为了让 setMessage(text) 有足够的时间用新值更新 dom,然后再使用 ref 设置光标。

如果不使用setTimeout,光标可能无法正确更新。

setTimeout(() => ref.current.setSelectionRange(newCursor,newCursor), 10)