Reactjs 在jsx上使用setTimout对Js/state进行反应

Reactjs 在jsx上使用setTimout对Js/state进行反应,reactjs,Reactjs,你好,我有一个聊天机器人,我正在尝试模拟一个打字机器人 也就是说,我有一个组件,在其中我将文本作为道具发送,然后我想在其上使用一个settimeout,在一段时间后显示文本并隐藏键入动画 但我有这样的问题: 这个数字出现了,这不是我的答案,他还反复执行我的设置 我再也无法想象我将如何用这个来模拟输入动画 我的商店 行动: export const ON_MESSAGE = 'ON_MESSAGE'; export const BOT_MESSAGE = 'BOT_MESSAGE'; expor

你好,我有一个聊天机器人,我正在尝试模拟一个打字机器人

也就是说,我有一个组件,在其中我将文本作为道具发送,然后我想在其上使用一个settimeout,在一段时间后显示文本并隐藏键入动画

但我有这样的问题:

这个数字出现了,这不是我的答案,他还反复执行我的设置 我再也无法想象我将如何用这个来模拟输入动画

我的商店

行动:

export const ON_MESSAGE = 'ON_MESSAGE';
export const BOT_MESSAGE = 'BOT_MESSAGE';
export const AWAIT_MESSAGE = 'AWAIT_MESSAGE';
export const FINISH = 'FINISH';
export const sendMessage = text => ({
  type: ON_MESSAGE,
  text,
});

export const botMessage = text => ({
  type: BOT_MESSAGE,
  text,
});

export const checkMessage = text => {
  return dispatch => {
    dispatch(sendMessage(text));
    dispatch(botMessage(verify(text)));
  };
};
我的减速机:

const initalState = {
  messages: [],
  waitResponse: false,
  bot: false,
};

const messageReducer = (state = initalState, action) => {
  switch (action.type) {
    case ON_MESSAGE:
      return {
        ...state,
        messages: [
          ...state.messages,
          {
            type: 'user',
            text: action.text,
            date: moment().format('DD/MM/YYYY-h:mm:ss'),
          },
        ],
        waitResponse: true,
        bot: true,
      };

    case BOT_MESSAGE:
      return {
        ...state,
        messages: [
          ...state.messages,
          {
            type: 'bot',
            text: action.text,
            date: moment().format('DD/MM/YYYY-h:mm:ss'),
          },
        ],
        waitResponse: false,
      };
    case FINISH:
      return [
        {
          ...state,
          waitResponse: false,
        },
      ];
    default:
      return state;
  }
};
还有我的jsx:

 <Styled.ChatLog>
        {chat.messages.map((rowData, index) => (
          <Styled.MessageFlexColumn key={index}>
            {rowData.type === 'user' ? (
              <UserText key={index}>{rowData.text}</UserText>
            ) : (
              <BotText key={index}>{rowData.text}</BotText>
            )}
            <div ref={messagesEndRef} />
            <Styled.Status />
          </Styled.MessageFlexColumn>
        ))}
        <div ref={messagesEndRef} />
      </Styled.ChatLog>

{chat.messages.map((行数据,索引)=>(
{rowData.type==='user'(
{rowData.text}
) : (
{rowData.text}
)}
))}
my UserText组件和botText组件:

const BotText = props => {
  const [text, setText] = useState(['']);
  const [showText, setShow] = useState(false);
  const getText = () => {
    setShow(!showText);
    return props.children;
  };
  return (
    <Styled.MessageWrapper>
      <Styled.BotImg src={BotLogo} />
      <Styled.ChatMessage>
        <Styled.TypingWrapper show={showText}>
          <span></span>
          <span></span>
          <span></span>
        </Styled.TypingWrapper>
        {setTimeout(() => {
          getText();
        }, 3000)}
      </Styled.ChatMessage>
    </Styled.MessageWrapper>
  );
};
constbottext=props=>{
const[text,setText]=useState(['');
const[showText,setShow]=useState(false);
常量getText=()=>{
设置显示(!showText);
返回道具。儿童;
};
返回(
{setTimeout(()=>{
getText();
}, 3000)}
);
};

这里还有改进的余地,但基本上这应该是可行的。每当文本属性更改时,它将显示键入动画3秒钟,然后切换到更新的文本

const BotText = props => {
  const {text} = props;
  const memoedText = useMemo(() => text, []);
  const [isTyping, setIsTyping] = useState(false);

  useEffect(() => {
    const timeoutId = setTimeout(() => {
      setIsTyping(false);
    }, [3000]);

    return () => clearTimeout(timeoutId);
  }, [])

  return (
    <Styled.MessageWrapper>
      <Styled.BotImg src={BotLogo} />
      <Styled.ChatMessage>
        <Styled.TypingWrapper show={isTyping}>
          <span></span>
          <span></span>
          <span></span>
        </Styled.TypingWrapper>
        {!isTyping && memoedText}
      </Styled.ChatMessage>
    </Styled.MessageWrapper>
  );
};
constbottext=props=>{
const{text}=props;
常量memonedtext=useMemo(()=>text,[]);
const[isTyping,setIsTyping]=useState(false);
useffect(()=>{
const timeoutId=setTimeout(()=>{
setIsTyping(假);
}, [3000]);
return()=>clearTimeout(timeoutId);
}, [])
返回(
{!isTyping&&memonedtext}
);
};
根据回复对话进行编辑:

const ChatLog = props => {
  const { chat } = props;
  const { messages } = chat;
  const [isTyping, setIsTyping] = useState(false);
  useEffect(() => {
    if (messages[messages.length - 1].type === "bot") {
      setIsTyping(true);
      const timeoutId = setTimeout(() => {
        setIsTyping(false);
      }, 3000);
    }
  }, [messages]);

  return (
    <div>
      {messages.map((message, idx) => {
        return message.type === "user" ? 
          <UserText key={idx}>
            {message.text}
          </UserText> : 
          <BotText 
            key={idx} 
            isTyping={isTyping && idx === messages.length - 1}
          >
            {message.text}
          </BotText

      }}
    </div>
  )
}

const BotText = props => {
  if (props.isTyping) return <div>typing stuff here</div>
  return <div>normal non-typing message render logic here</div>
}
const ChatLog=props=>{
const{chat}=props;
const{messages}=chat;
const[isTyping,setIsTyping]=useState(false);
useffect(()=>{
如果(消息[messages.length-1]。类型==“bot”){
setIsTyping(真);
const timeoutId=setTimeout(()=>{
setIsTyping(假);
}, 3000);
}
},[信息];
返回(
{messages.map((message,idx)=>{
返回消息。类型==“用户”?
{message.text}
: 
{message.text}
{
如果(props.isTyping)在此处返回键入内容
在此处返回正常的非键入消息呈现逻辑
}

我就是这样做的,但我在键入新文本时遇到了问题。旧文本也会重新制作动画。请尝试将我执行的位置更改为
[text]
哦,对不起,我的坏消息,我可以用我的操作和减速机编辑响应,让您看看是否有可能用减速机做类似的事情吗?当然,但我个人认为这种行为在组件内会处理得更好。真的,我花了几个小时考虑它,我找到了一个选项,我将编辑我的操作n和reducer以及我的jsx,如果你能告诉我哪里可以改进的话