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