【问题标题】:Component not reloading but state is changing with useState组件未重新加载,但状态随 useState 发生变化
【发布时间】:2019-11-12 10:54:28
【问题描述】:

我对反应并不陌生,但我是使用钩子的新手,今天我在玩一系列选定元素和选择/取消选择。

如果它们被选中,则显示一个图标,如果没有,则显示另一个图标(我只是更改名称 prop,而不是组件本身。

我每次渲染的 console.log 都显示了正确的结果,但它在 JSX 上没有按预期工作。

当我取消选择时,渲染似乎只会重新加载(显示右侧图标)。以列表的形式解释程序和我的问题:

  1. 所有元素都被选中
  2. 我取消选择一个元素(从列表中删除),图标发生变化。
  3. 我选择返回元素(添加到列表),图标没有改变。
  4. 我取消选择另一个元素,然后它工作并且组件是 重新加载

这是我的对象数组:

const dies = [
  {
    id: 1,
    nomDia : 'Dies',
    dataDia : 'previs'
  },
  {
    id: 2,
    nomDia : 'Dies',
    dataDia : 'previs'
  },
  {
    id: 3,
    nomDia : 'Dies',
    dataDia : 'previs'
  }
]

这是 useSate 声明:

const [diesSeleccionats, setDiesSeleccionats] = useState(dies)

这里是检查是否被选中的函数以及从选定列表中添加/删除的函数:

// check if selected
const estaSeleccionat = (dia) => {
    return diesSeleccionats.findIndex((aDia) => aDia.id === dia.id ) != -1
  }
// remove selected or add selected
const gestionarSeleccionats = (dia) => {
    if(estaSeleccionat(dia)){
      return diesSeleccionats.filter((aDia) => aDia.id !== dia.id)
    } else {
      diesSeleccionats.push(dia)
      return diesSeleccionats
    }
 }

这是组件:

   dies.map((dia) => (
                      <View key={dia.id} style={{flexDirection: 'row', marginTop: 5, alignSelf: 'flex-end'}}>
                        <TouchableOpacity
                          style={{backgroundColor: Colors.llistat1 + 'CC'}}
                          key={dia.id}
                          onPress={() => setDiesSeleccionats(gestionarSeleccionats( dia ))}
                        >
                            <Text style={{fontSize: 18, color: Colors.titolsPantalles}}> {dia.nomDia} </Text>
                        </TouchableOpacity>
                        <TouchableOpacity
                          style={{
                            minWidth: 24,
                            backgroundColor: Colors.llistat1 + 'CC',
                            marginLeft: 5,
                            paddingHorizontal:5,
                            justifyContent:'center', alignItems: 'center'}}
                          onPress={ () => setDiesSeleccionats(gestionarSeleccionats( dia ))}
                          >
                          <Ionicons name={ estaSeleccionat( dia ) ? "md-checkmark" : "md-close"} size={18} color={Colors.titolsPantalles} />
                        </TouchableOpacity>
                      </View>
                    ))

您可以看到 Ionicons> 的名称是由元素是否在所选列表中定义的。

我每次重新渲染的日志都显示了正确的结果。 (检查函数的布尔值,以及对象数组上的正确元素)

谢谢。

【问题讨论】:

    标签: javascript reactjs react-native react-hooks


    【解决方案1】:

    我认为这个问题与改变 diesSeleccionats 而不是复制它有关。我认为您需要将其复制并提供给setDiesSeleccionats,以便 React 可以分析差异并呈现正确的更新状态。

    const gestionarSeleccionats = (dia) => {
        const selections = [...diesSeleccionats];
        if(estaSeleccionat(dia)){
          return selections.filter((aDia) => aDia.id !== dia.id);
        } else {
          selections.push(dia)
          return selections;
        }
     }
    

    【讨论】:

    • 在发布问题后,我去洗澡了,我向上帝发誓,我在洗澡时得出了同样的结论,问题必须出在使用相同的“对象”上。顺便说一句,现在它的工作就像一个魅力!现在我想,你有没有类似的解释语法: const selections = [...diesSeleccionats];我的意思是,我知道它的作用,但我想知道怎么做。谢谢!!
    • @JosepVidal 当然,它被称为扩展语法。你可以阅读更多关于它here
    猜你喜欢
    • 2021-06-25
    • 1970-01-01
    • 2021-07-09
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 2021-06-12
    • 2017-03-08
    • 2021-10-11
    相关资源
    最近更新 更多