首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React、console.log和呈现显示不同的值

React、console.log和呈现显示不同的值
EN

Stack Overflow用户
提问于 2020-10-25 06:30:26
回答 4查看 1.4K关注 0票数 2

看来,记录在控制台上的对象与上显示的内容不匹配,下面这个简单的示例让我感到困惑。在这里,按钮切换数组的顺序,并作出反应似乎呈现上一个列表。

===更新3 ====

cuprite是对象同情,其中setState(list=>list.push(12))会变异列表,但不会触发setState,因为列表的id仍然是相同的。

如果您将状态挂钩更新为与当前状态相同的值,则React将在不呈现子状态或触发效果的情况下退出。(React使用Object.is比较算法。) 反应useState文档

===更新2 ====

我想我找到了解决办法。罪魁祸首似乎是对象的可更改性,解决方法是在溶液砂箱中创建排序列表的深度副本。我认为我发现了一种未定义的反应行为,因为列表的可更改性不应导致console.log(list)<h1>list</h1>之间的任何差异,如下图所示。ReactJS中状态数组的正确修改

===更新1 ====

沙盒,它包含与下面所示代码相同的代码。

我的排序函数没有什么问题!如果是升序,那么应该首先使用较小的元素,这意味着比较函数(e1,e2)=>e1-e2是正确的。

如果compareFunction(a,b)返回小于0,则对低于b的索引排序a(即a优先)。比较函数Mozilla

代码语言:javascript
复制
const {useState, useEffect, useReducer} = React;

function App() {
  const [list, setList] = useState([0,1]);
  const [isAscending, toggle] = useReducer(isAscending=>!isAscending, true);
  // update the order of the list
  useEffect(()=>{
    if (isAscending) {
      setList(list.sort((e1,e2)=>e1-e2));
    } else {
      setList(list.sort((e1,e2)=>e2-e1));
    }
  },[list, isAscending]);
  // render
  return (
    <div>
    {console.log("list[0] should be",list[0])}
    <button onClick={toggle}>{isAscending?"Ascending":"Descending"}</button>
    <h1>list[0]: {list[0]}</h1>
    </div>
  )
}

ReactDOM.render(<App/>, document.querySelector('.App'));
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div class='App'/>

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-11-03 08:55:21

根据MDN,javascript排序函数会对数组进行变异。

sort()方法对数组的元素进行排序,并返回排序后的数组。

当你写:

代码语言:javascript
复制
setList(list.sort((e1, e2) => e1 - e2));

在setList对其进行变异之前,您是在变异列表。

setList检查给定的值是否与以前的值不同,然后进行呈现。

但是setList认为没有什么不同,因为list值已经通过排序方法更新了。

正因为如此,渲染似乎落后了一步。

所以你应该写:

代码语言:javascript
复制
setList([...list].sort((e1, e2) => e1 - e2));

还有一件事:

我觉得你应该改变一下

代码语言:javascript
复制
{isAscending ? "Ascending" : "Descending"}

代码语言:javascript
复制
{isAscending ? "Descending" : "Ascending"}

因为它是一个切换按钮

票数 3
EN

Stack Overflow用户

发布于 2020-11-02 13:34:46

您的初始顺序是升序。单击该按钮时,第一次切换要从升序移动到降序的顺序。

这意味着

代码语言:javascript
复制
if (isAscending) {
    // Logic for descending should come here
    setList(list.sort((e1, e2) => e2 - e1));
} else {
    // Logic for ascending should come here
    setList(list.sort((e1, e2) => e1 - e2));
}

检查这里的代码,让我知道这是否是你要找的。代码沙箱:排序列表不呈现

票数 2
EN

Stack Overflow用户

发布于 2020-10-25 06:35:29

list回调处有useEffect值的闭包,应该将其添加到dep数组中:

代码语言:javascript
复制
function App() {
  const [list, setList] = useState([0, 1]);
  const [isAscending, toggle] = useReducer((isAscending) => !isAscending, true);

  useEffect(() => {
    setList(list.sort((e1, e2) => (!isAscending ? e1 - e2 : e2 - e1)));
  }, [list, isAscending]);

  return (
    <div>
      <button onClick={toggle}>
        {isAscending ? "Ascending" : "Descending"}
      </button>
      <pre>{JSON.stringify(list)}</pre>
    </div>
  );
}

请注意,如果您有eslint,您应该得到一个警告。

https://codesandbox.io/s/react-template-forked-08eft?file=/index.js:99-684

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64520983

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档