React Native:基于Array.map()的渲染组件不会在状态更改时更新

时间:2020-09-24 17:01:42

标签: typescript react-native react-typescript

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

主页(主要组件):

var nameArr = []; 
var costStr = ""; 
var costArr = []; 
var totalCost = 0;
export default function Product(props) {
  const handleClick = (e) => {
    totalCost = 0;
    nameArr.push(`${props.name}`);
    costStr += `${props.price}, `;
    costArr = costStr.split`,`.map((x) => +x);
    for (var i = 0; i < costArr.length; i++) {
      totalCost += costArr[i];
    }   
    console.log(
            `${props.name} added to basket at price of £${props.price}\nbasket: ${nameArr}\ntotal: £${totalCost}`
    );  
  };  
  return (
    <div className={styles.product}>
      <Link href={props.link}>
        <img src={props.img} alt={props.name} />
      </Link>
      <Link href={props.link}>
        <h3>{props.name}</h3>
      </Link>
      <span>{props.price}</span>
      <button onClick={handleClick}>Add to Bag</button>
    </div>
  );  
}

指标组件:

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; 的状态在单击可触摸区域时按预期进行了更改,但是组件中没有可见的更改。

2 个答案:

答案 0 :(得分:1)

您需要使用一个全新的对象设置状态,以便它不会通过浅表比较。

您可以执行以下操作:

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);
};

答案 1 :(得分:0)

我已经验证了开关的状态正在按预期更改

您对此有100%的把握吗?

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

此代码不会切换开关值。 map调用会计算并返回转换后的数组,但不会在原位置更改它,然后您会丢弃结果,然后每次使用完全相同的未触发setSwitches值调用base之前。另外,当您似乎想要切换base的状态时,您正在使用switches进行切换。

您想要更多类似这样的东西:

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