当前位置: 首页 > 知识库问答 >
问题:

为什么不正确更新我的状态?[副本]

仲浩歌
2023-03-14

我通过使用map函数迭代来显示我的状态,这是一个数组。此外,我有一个按钮,在点击反转数组。

import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
import "./App.css";

const App = (props) => {
  const [reverse, setReverse] = useState(false);

  const [arr, setArr] = useState([]);

  useEffect(() => {
    let newArr = props.arr;

    newArr = newArr.reverse();

    setArr(newArr);
  }, [reverse, props.arr]);

  return (
    <div className="App">
      <button
        onClick={() => {
          setReverse(!reverse);
        }}
      >
        Reverse
      </button>
      {arr.map((e, i) => {
        return (
          <div key={i}>
            <p>{e}</p>
          </div>
        );
      })}
    </div>
  );
};

App.propTypes = {
  arr: PropTypes.array,
};

export default App;

我认为我想做什么是相当明显的。但这对我不起作用,我不知道为什么。我必须单击两次来完成第一次还原,出现了奇怪的情况,即呈现的数组和Chrome中React开发工具在组件状态中显示的数组不匹配。

我无法解释这种行为。我开始认为这与我从道具中获得阵列有关,但我真的不知道。有什么想法吗?

共有3个答案

计光赫
2023-03-14

主要错误是您将道具分配给newArr变量,而不是arr,因此每次都不是arr的新状态被反转,而是props的原始数组。另外,在更改道具时,最好再添加一个useffect。我在下面提供了一个正确代码的示例。如果有错误,我道歉,我的英语说得不好

  useEffect(() => {
    setArr(props.arr);
  }, [props.arr]);

  useEffect(() => {
    if (!arr.length) return;

    let newArr = arr.length ? [...arr] : [...props.arr];
    newArr = [...newArr.reverse()];
    setArr(newArr);
  }, [reverse]);

姬昀
2023-03-14

这是因为useffect()钩子在组件的挂载上运行并反转数组,尽管您没有单击反转按钮。

尝试添加逻辑以避免挂载上发生的第一次反转。

这可能对你有用,

  useEffect(() => {
      if(arr.length>0){
         let newArr = props.arr;
         newArr = newArr.reverse();
         setArr(newArr);
      }
  }, [reverse, props.arr]);
叶举
2023-03-14

有几个改进要做。有些是bug,有些只是反模式。

首先要注意的是,反向改变了原始数组。你不应该在React中改变状态或道具。

第二种是反模式,涉及将道具复制到不需要复制的状态。

React文档说状态是指随时间变化的值。它说如果一个值可以从道具中导出,它就不是状态。

你能根据组件中的任何其他状态或道具来计算它吗?如果是这样,那就不是国家。

这就是我们在本案中的情况。

与其将proparr复制到状态并在那里反转,我们可以只使用prop和一个临时变量以更少的代码完成相同的目标。

const {useState, useEffect} = React;

const App = (props) => {
  const [reverse, setReverse] = useState(false);
  
  let array = [...props.arr]; // New reference so we will not mutate props
  if (reverse) {
    array.reverse();
  }

  return (
    <div className="App">
      <button
        onClick={() => {
          setReverse(!reverse);
        }}
      >
        Reverse
      </button>
      {array.map((e, i) => {
        return (
          <div key={i}>
            <p>{e}</p>
          </div>
        );
      })}
    </div>
  );
};

ReactDOM.render(<App arr={[1,2,3]} />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
 类似资料:
  • 我有一个组件,可以创建三个单选按钮。Cicking one应该更新我在别处的上下文存储。 我的状态是这样的: 我将状态存储为: 然后我的组件触发函数: 当我单击一个按钮时,函数将启动,但console.log将显示以前的状态,而不是新更新的状态。同样,我的上下文也会落后一步更新。 这到底是怎么回事?

  • 问题内容: 抱歉,我真的很想念React中子组件内部的传递。 我已经实现了一个包含3个组件的待办事项列表。 有一个组成部分和一个组成部分。状态仅存储在组件中。 显示器起步不错,因此可以看到道具。但是在提交表单后,我收到了以下错误: TypeError:this.props.tasks.map不是函数 当我console.log时,我没有得到我的数组,而是数组的长度。 你知道为什么吗? 编辑 :谢谢

  • 问题内容: 我已经尝试了两个类组件: 并使用功能组件: 页面上显示的x值永远不会改变,或者似乎是随机改变的。是什么赋予了? 问题答案: 当您告诉React某些更改时,React仅知道使用其为状态管理提供的功能来重新渲染: 另外,功能组件应该是 纯 组件(没有副作用),因此要更新它们,React会给我们带来麻烦: 因此,您不能只是分配给一个变量并期望React知道:您必须使用它的更新函数,以便它知道

  • 但是,正确的数据条目在被调用时会打印出来。我试着在网上寻找我应该做什么的答案,但我找不到任何实际可行的东西。我刚刚开始学习Java,所以可能有一个非常简单的答案,我只是忽略了。如果有人有什么想法,我将不胜感激。

  • 问题内容: 我正在创建一个小型Java Jpanel游戏,其中应该有一个火箭,它通过箭头上下移动,并通过太空射击。 触发方法应按以下方式工作:按下空格键,东西触发并在屏幕上移动,然后当它碰到某个x时,它就会消失。此外,您只能发射一次,直到另一颗子弹消失为止。 我不知道我在做什么错。首先,在我的代码启动后,您会看到子弹在屏幕上飞舞。 2,子弹没有消失。 第三,即使其他子弹仍然可见,它也允许我再次开火

  • choice5是一个JComboBox 从choice5中选择项目时 被称为(编辑:对于我可以选择的每个项目,我可能有一个不同的jtable我想要显示) 编辑(SSCCE): MyTableModel