javascript 即使我使用了useeffect,组件也不会重新呈现,并且状态正在更改?

kb5ga3dv  于 2022-12-28  发布在  Java
关注(0)|答案(3)|浏览(119)

我正在使用react native并创建一个聊天应用程序。现在我在数组中有几个消息对象,当我键入消息并单击发送时,我现在在平面列表中呈现它们。在消息数组中添加消息后,我键入的消息变得清晰。但消息不会与其余消息一起添加到屏幕上。因为当我单击发送时,组件似乎不会重新呈现原因,消息从字符串中消失,但在列表数组中,该消息与其余消息一起成功添加
现在,你能告诉我这里的代码出了什么问题吗?

const ChatComponent = (props) => {
  const [message, setMessage] = useState('');
  const [messages, setMessages] = useState([
    { id: '1', text: 'Hello, how are you?', sender: 'John' },
    { id: '2', text: 'Im good, thanks for asking!', sender: 'Jane' },
    { id: '3', text: 'What have you been up to?', sender: 'John' },
    { id: '4', text: 'Not much, just working and taking care of some errands.', sender: 'Jane' },
  ]);

  const listRef = useRef(null);

  useEffect(() => {
    setMessages(messages);
  }, [messages]);

  const handleSend = () => {
    LayoutAnimation.configureNext({
        duration: 500,
        update: {
          type: LayoutAnimation.Types.easeInEaseOut,
        },
      }, () => {
        setMessages([...messages, { id: messages.length + 1, text: message, sender: 'Me' }]);
        setMessage('');
      });
  };

  return (
    <SafeAreaView style={styles.container}>
      <FlatList
        ref={listRef}
        data={messages}
        renderItem={({ item }) => (
          <View style={[styles.messageContainer, item.sender === 'Me' && styles.me]}>
            <Text style={[styles.sender, item.sender === 'Me' && styles.me]}>{item.sender}:</Text>
            <Text style={[styles.message, item.sender === 'Me' && styles.me]}>{item.text}</Text>
          </View>
        )}
        keyExtractor={item => item.id}
      />
      <View style={styles.inputContainer}>
        <TextInput
          style={styles.input}
          placeholder="Type a message..."
          value={message}
          onChangeText={text => setMessage(text)}
        />
        <TouchableOpacity style={styles.button} onPress={handleSend}>
          <Text style={styles.buttonText}>Send</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
};
ie3xauqp

ie3xauqp1#

更新LayoutAnimation回调内的代码与React UI呈现不同步。
删除按钮按下事件处理程序中的布局动画代码,并将其委托给useEffect,如下所示:

useEffect(()=>{
      LayoutAnimation.configureNext({
        duration: 500,
        update: {
          type: LayoutAnimation.Types.easeInEaseOut,
        },
      });

  },[messages.length])

  const handleSend = () => {
      setMessages([...messages, { id: messages.length + 1, text: message, sender: 'Me' }]);
      setMessage('');
  };

您将同时维护布局动画和状态更新。
工作演示-https://snack.expo.dev/@emmbyiringiro/ea7d26

olhwl3o2

olhwl3o22#

删除useEffect。
它将无限地重新呈现组件,因为您设置的是dependency数组中包含的相同useState

//remove this
useEffect(() => {
    setMessages(messages);
  }, [messages]);
n1bvdmb6

n1bvdmb63#

您需要删除此setFunction setMessage('');,因为react使用queue,这意味着消息状态将获得最后一个状态值。

相关问题