【问题标题】:React Native: Array.map()-based rendered components not updating on state changeReact Native:基于 Array.map() 的渲染组件不会在状态更改时更新
【发布时间】:2021-01-11 00:30:18
【问题描述】:

我有一些从 Array.map() 中渲染的组件,即使状态(与所述数组有关)发生变化也不会更新,我不知道为什么会这样。

首页(主要组件):

import React, { useState } from 'react';
import { View, TouchableOpacity } from 'react-native';
import { base } from './data';

import Indicator from './components/Indicator';

const Home = () => {
  const [switches, setSwitches] = useState(base);

  const handleToggle = (id: number) => {
    base.map(switch => {
      switch.on =
        (switch.on && switch.id !== id) || (!switch.on && switch.id === id)
          ? !switch.on
          : switch.on;
    });
    setSwitches(base);
  };

  return (
    <View>
      {switches.map(switch => (
        <TouchableOpacity
          onPress={() => handleToggle(switch.id)}
          key={switch.id}
        >
          <Indicator
            color={switch.color}
            on={switch.on}
          />
        </TouchableOpacity>
      ))}
    </View>

指标组件:

import React from 'react';
import { View } from 'react-native';

import { On, Off } from './Indicators';

interface IndicatorProps {
  color: string;
  on: boolean;
}

const Indicator: React.FC<IndicatorProps> = ({ color, on }) => {
  return (
    <View>
      {on ? <On /> : <Off />}
    </View>
  );
};

export default Indicator;

我已验证switches 的状态在单击可触摸区域时按预期发生变化,但组件中没有发生可见变化。

【问题讨论】:

    标签: typescript react-native react-typescript


    【解决方案1】:

    我已验证开关的状态正在按预期变化

    您对此 100% 确定吗?

        base.map(switch => {
          switch.on =
            (switch.on && switch.id !== id) || (!switch.on && switch.id === id)
              ? !switch.on
              : switch.on;
        });
        setSwitches(base);
    

    此代码不会切换开关值。 map call 计算并返回转换后的数组,但不会更改它,然后你会丢弃结果,然后每次调用 setSwitches 并使用完全相同的未切换 base 值。此外,您正在使用base 进行切换,此时您可能想要切换switches 的状态。

    你想要更像这样的东西:

        setSwitches(switches.map(switch => {
          switch.on =
            (switch.on && switch.id !== id) || (!switch.on && switch.id === id)
              ? !switch.on
              : switch.on;
        }));
    

    【讨论】:

    • 我认为它也不会,但是是的,我 100% 确定状态正在更新。
    • 这里的固定代码对你有用吗?有一些不同的问题在交互(例如,你也在改变 switch 对象,这可能确实会改变状态而不影响反应状态)但我认为这应该可行。
    • 我之前尝试过,但也没有用。
    【解决方案2】:

    你需要用一个全新的对象设置状态,这样它就不会通过浅层比较。

    你可以这样做:

    const handleToggle = (id: number) => {
      const newState = switches.map(switch => ({
        ...switch,
        on: (switch.on && switch.id !== id) || (!switch.on && switch.id === id) 
          ? !switch.on
          : switch.on
      }));
      setSwitches(newState);
    };
    

    【讨论】:

    • 知道了,谢谢。我不知道为什么,但是当我尝试使用三元 ... 时,它不起作用,一定是错过了一些东西。这工作得很好:)
    猜你喜欢
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 2018-03-17
    • 2018-12-12
    • 2020-03-03
    相关资源
    最近更新 更多