【问题标题】:Why is my React Native component not re-rendering on state update?为什么我的 React Native 组件没有在状态更新时重新渲染?
【发布时间】:2021-04-13 09:46:18
【问题描述】:

这几天我一直在为这个 React-Native 组件苦苦挣扎。您可能应该知道 React-Native 对我来说是一种新事物...抱歉,如果解决方案对您来说很明显。

我正在使用 react-native-maps,我的地图上有几个标记。他们每个人都有一些数据存储在我的状态中,我希望标注在按下时显示这种状态的一部分。 这是我的状态:

const [markersDetails, setMarkersDetails] = useState([]);
const [activeMarker, setActiveMarker] = useState({});

我的 activeMarker 被这个函数更新了:

const markerSearch = (markerId) => {
  let stockMarker = markersDetails.find((singleMarker) => {
    return Number(singleMarker.idMarker) === markerId;
  });
  console.log("Stock ", stockMarker);
  setActiveMarker(stockMarker);
  console.log("State ", activeMarker);
};

这个函数在我的返回中被调用,带有任何标记的 onPress :

<Marker
  key={Number(marker.index)}
  coordinate={{
    latitude: Number(marker.latitude),
    longitude: Number(marker.longitude),
  }}
  pinColor="blue"
  onPress={() => {
    markerSearch(Number(marker.index));
  }}
>
  {activeMarker !== {} && activeMarker.markerName && (
    <Callout>
      <View>
        <Text>{activeMarker.markerName}</Text>
      </View>
    </Callout>
  )}
</Marker>

但每当我按下标记时,标注会立即打开,而我的状态尚未更新。所以标注中的文本要么是指前一个标记,要么是空的(如果它是我按下的第一个标记)。 我检查了console.log,我的状态明显更新了,但需要更多时间。而且我不知道为什么当这个状态更新时我的标注没有重新渲染。 我已经尝试了很多方法来使它起作用,但我无法弄清楚...

【问题讨论】:

  • 在 onPress 中,您的意思是 marker.index,它看起来像是 markersDetails 数组中的索引,而在您使用 find 的 markerSearch 函数中,您使用数组中 singleMarker 元素的值,我想您可能需要将其更改为: let stockMarker = markersDetails.find((singleMarker, singleMarkerIndex) => { return singleMarkerIndex === markerId; });
  • 感谢您的输入@elirand5,但此解决方案在这种情况下不起作用,这里的“索引”不是数组内的位置而是数据库内的位置,因此它们不一样。无论如何,问题仍然是状态更新速度和组件渲染速度之间的差异和/或状态更新后缺乏重新渲染。

标签: reactjs react-native google-maps react-native-maps


【解决方案1】:

尝试做这样的事情:

  1. 您可以将该部分提取到一个新组件中
  2. 然后在这个里面使用 useEffect 钩子
export default function CalloutComponent({activeMarker}) {
  const [markerName, setMarkerName] = useState('')
  
  useEffect(() => {
    setMarkerName(activeMarker?.markerName)
  }, [activeMarker?.markerName])

  if(!!markerName) return null

  return (
    <Callout>
      <View>
        <Text>{markerName}</Text>
      </View>
    </Callout>
  )
}
  1. 并在您的主视图中使用这个新组件
<Marker
  ...
>
  <CalloutComponent activeMarker={activeMarker}/>
</Marker>

【讨论】:

  • 感谢胡安的意见。不幸的是,我今天早些时候已经将标注提取到另一个组件,问题仍然存在。
猜你喜欢
  • 2020-10-24
  • 1970-01-01
  • 2019-09-23
  • 2017-01-14
  • 2020-03-10
  • 1970-01-01
  • 1970-01-01
  • 2020-11-04
  • 2021-11-18
相关资源
最近更新 更多