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

使用useState钩子时对组件渲染进行两次反应

郎喜
2023-03-14

我无法理解为什么我的AppReact组件呈现两次,如下面的gif所示。

我插入了一个控制台。在返回组件之前记录日志,查看组件渲染的次数。

每当我移除useState钩子时,我的应用程序只会呈现一次我认为应该呈现的效果。任何关于为什么会发生这种情况的指导都是受欢迎的

import React, { useState, useEffect } from 'react';

const ListItem = ({ title, url, author, num_comments, points }) => {
  return (
    <div>
      <span>
        <a href={url} target='_blank' rel='noopener noreferrer'>
          {title}
        </a>{' '}
        by {author}
      </span>
      <br />
      <span>Comments: {num_comments}</span>
      <br />
      <span>Points: {points}</span>
      <hr />
    </div>
  );
};

const List = ({ list }) => {
  return list.map(({ objectID, ...item }) => (
    <ListItem key={objectID} {...item} />
  ));
};

const Search = ({ search, onSearch }) => {
  return (
    <div>
      <label htmlFor='search'>Search: </label>
      <input id='search' type='text' value={search} onChange={onSearch} />
      <p>
        Searching for <strong>{search}</strong>
      </p>
    </div>
  );
};

const App = () => {
  const stories = [
    {
      title: 'React',
      url: 'https://reactjs.org/',
      author: 'Jordan Walke',
      num_comments: 3,
      points: 4,
      objectID: 0,
    },
    {
      title: 'Redux',
      url: 'https://redux.js.org/',
      author: 'Dan Abramov, Andrew Clark',
      num_comments: 2,
      points: 5,
      objectID: 1,
    },
  ];

  const [search, setSearch] = useState(localStorage.getItem('search') || '');

  useEffect(() => {
    localStorage.setItem('search', search);
  }, [search]);

  const handleSearch = (event) => {
    setSearch(event.target.value);
  };

  console.log('rendered');

  return (
    <div className='App'>
      <h1>My Hacker Stories</h1>
      <Search search={search} onSearch={handleSearch} />
      <hr />
      <List
        list={stories.filter((story) =>
          story.title.toLowerCase().includes(search.toLowerCase())
        )}
      />
    </div>
  );
};

export default App;

共有3个答案

养枫涟
2023-03-14

您的setSearch正在更新输入框的vue,然后当搜索更改时,使用效果再次更新它。

移除useffect

然后

const handleSearch = (event) => {
    setSearch(event.target.value);
    localStorage.setItem('search', event.target.value)
  }

下面是一个沙盒链接:https://codesandbox.io/s/dawn-night-h2xiz?file=/src/App.js

它确实不能解决问题,但将来可能会避免一些问题。

双渲染只应在开发模式下进行,而不应在生产模式下进行。见丹·阿布拉莫夫的回复:https://github.com/facebook/react/issues/15074

辛渝
2023-03-14

甚至我也想知道为什么我的控件渲染两次。

我在我的大多数组件中都没有useEffect钩子,我只是在用户在输入框中输入数据时设置状态(不可变)。这也发生在每个具有两个why绑定的组件中。

DevTools:我在浏览器中尝试了我的应用程序,但没有安装DevTools,仍然存在同样的问题。

做出反应。StrictMode我认为这是潜在的罪魁祸首。当我从index.js删除此标记时,所有组件都开始正常工作。我还在官方留档中读到,严格模式检查仅在开发模式下执行,在生产构建中被忽略。

这使我认为我们的代码是正确的,我们可以忽略dev中的重新呈现问题。

章晋鹏
2023-03-14

看看这个:https://github.com/facebook/react-devtools/issues/1297

“意外的重新呈现”实际上并不是由useEffect引起的,而是DevTools通过单独重新呈现函数组件来“检查”挂钩值的方式。

虽然我知道意外的渲染在某些情况下可能表明问题,但这种特殊的渲染实际上不应该是问题,原因有几个:

渲染不是递归的。(不渲染子组件。)渲染只发生在安装了DevTools的用户身上,即使如此,也只会影响单个组件(树中当前选定的组件)。渲染没有副作用(例如DOM不会被更新)。

 类似资料:
  • 也许你们中的一些人可以帮我睁开眼睛。 我不明白为什么在这段代码中:https://codesandbox.io/s/use-state-renders-twice-6r1xl组件应用程序在安装并单击按钮时呈现两次(console.log被调用两次) 代码: 结果: 它只是一个功能组件挂钩!

  • 所以就像标题所说的,我的应用程序的主页因为某种原因渲染了两次,我不知道为什么。从我的浏览器路由器,我最初调用一个JS文件,从那里我调用我的HomePage组件和React路由器,但然后我的页面渲染两次,我不知道为什么。 我的浏览器路由器(index.js): 然后pp.js被称为: 然后我的主页组件(index.jsx): 和路线。js: 但是我的页面是这样渲染的: 我真的很困惑,所以任何建议都会

  • 我有一个组件,它获取作为道具的项目集合,并将它们映射到作为父组件的子组件呈现的组件集合。我们使用存储在WebSQL中的图像作为字节数组。在函数中,我从项中获取图像ID,并对进行异步调用,以获取图像的字节数组。我的问题是,我不能在React中传播这个promise,因为它不是为了处理渲染中的promise而设计的(至少我可以告诉你)。我来自一个背景,所以我想我正在寻找类似于关键字的东西来重新同步分支

  • 问题内容: 随着React 中钩子的引入,现在的主要困惑是何时将函数组件与钩子和类组件一起使用,因为在钩子的帮助下,甚至可以在函数组件中获得和部分使用。所以,我有以下问题 钩子的真正优点是什么? 何时使用带有钩子的函数组件和类组件? 例如,带有钩子的功能组件不能像类组件那样帮助性能。他们没有执行就不能跳过重新渲染。还有其他原因吗? 提前致谢。 问题答案: 引入和其他特性(例如和)的思想是帮助减少必

  • 我有一个使用输入钩子组件,其工作原理如下: 它获取一个(input,inputName)并返回一个挂钩的输入组件。当我想动态地改变视图中现有输入的可见性时,我得到一个错误:渲染的钩子比之前渲染的多。