简体   繁体   English

state 更新后 React Native 中的组件错误呈现

[英]Component in React Native wrongly rendered after state update

I'm having a really weird problem with my React Native component.我的 React Native 组件有一个非常奇怪的问题。 Component's state is correctly updated, but it is not reflected on what is rendered by the component.组件的 state 已正确更新,但未反映在组件呈现的内容上。

Here is what my component looks like (I didn't include imports and other parts of the code that are irrelevant):这是我的组件的样子(我没有包含导入和其他不相关的代码部分):

export default function MessageActionsModal({ 
  message,
  actions,
  onClose
}) {
  const [dimensions, setDimensions] = useState(null);
  const [messageActions, setMessageActions] = useState([]);

  useEffect(() => {
    if (message !== null) {
      setMessageActions(actions.map((a) => ({
        ...a,
        onPress: () => {
          a.onPress(message?.item);
          onClose();
        }
      })))
    } else {
      setMessageActions([]);
    }
  }, [message, actions, onClose]);
  
  if (message === null) {
    return null;
  }

  return (
    <Portal>
      <TouchableOpacity
        style={styles.messageActionsModal}
        activeOpacity={0}
        onPress={onClose}
      >
        <Portal style={styles.messageActionsModalInnerContainer}>
          <MessageListItem
            style={[
              styles.message,
              getMessagePositionAndDimensions(message)
            ]}
            {...message.item}
          />
          <View
            style={[
              styles.messageActionsMenu,
              getMenuPosition(dimensions, message)
            ]}
            {...dimensions === null && {
              onLayout: ({ nativeEvent }) => setDimensions({
                width: nativeEvent.layout.width,
                height: nativeEvent.layout.height
              })
            }}
          >
            <Text>{'LEN'}{messageActions.length}</Text>
            <Text>{'LOG'}{console.log(messageActions.length)}</Text>

            {messageActions.map((a) => (
              <Button
                key={a.title}
                style={styles.messageActionButton}
                title={a.title}
                variant="text"
                startIcon={a.icon}
                startIconProps={{
                  style: styles.messageActionButtonIconWrapper,
                  iconStyle: styles.messageActionButtonIcon,
                  fill: Colors.yellow
                }}
                onPress={a.onPress}
              />
            ))}
          </View>
        </Portal>
      </TouchableOpacity>
    </Portal>
  );
}

So basically, after messageActions are updated in the useEffect , component renders incorrectly and neither message action is rendered (although one item should be rendered).所以基本上,在messageActions中更新useEffect后,组件呈现不正确,并且两个消息操作都没有呈现(尽管应该呈现一个项目)。

Another interesting thing is that the following code renders "LEN 0", but it logs "LOG 1" in the console.另一个有趣的事情是,以下代码呈现“LEN 0”,但它在控制台中记录“LOG 1”。

<Text>{'LEN'}{messageActions.length}</Text>
<Text>{'LOG'}{console.log(messageActions.length)}</Text>

What am I doing wrong here?我在这里做错了什么?

You can try memoizing actions instead of using useEffect .您可以尝试记忆动作而不是使用useEffect Here's an example:这是一个例子:

const messageActions = useMemo(() => {
    if (message === null) {
      return [];
    }
    
    return actions.map((a) => ({
        ...a,
        onPress: () => {
          a.onPress(message?.item);
          onClose();
        }
      }));
}, [message, actions, onClose]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM