我定义了一个场景:我们有一个使用父项的道具及其自身状态的组件。
有两个组件DC和JOKER,下面是我的步骤:
我想问一下为什么JOKER渲染两次(步骤3和5),而第一个渲染浪费了性能。 我只是不想执行步骤3 。 如果在类组件中,我可以使用componentShouldUpdate来避免它。但是胡克斯有同样的东西吗?
下面的我的代码,或打开此网站https://jsfiddle.net/stephenkingsley/sw5qnjg7/
import React, { PureComponent, useState, useEffect, } from 'react';
function JOKER(props) {
const [count, setCount] = useState(props.count);
useEffect(() => {
console.log('I am JOKER\'s useEffect--->', props.count);
setCount(props.count);
}, [props.count]);
console.log('I am JOKER\'s render-->', count);
return (
<div>
<p style={{ color: 'red' }}>JOKER: You clicked {count} times</p>
</div>
);
}
function DC() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => {
console.log('\n');
setCount(count + 1);
}}>
Click me
</button>
<JOKER count={count} />
</div>
);
}
ReactDOM.render(<DC />, document.querySelector("#app"))
答案 0 :(得分:32)
这是StrictMode的故意功能。这只会发生在 开发,并有助于发现意外的副作用 渲染阶段。我们只对带有挂钩的组件执行此操作,因为 更有可能在错误的地方意外产生副作用。 -gaearon commented on Mar 9, 2019
答案 1 :(得分:0)
我不确定我是否理解您的问题,但是可以。
当<DC />
组件更改状态时,它将新的状态值count
传递给组件Joker。此时,将重新渲染组件,以解决第一个更改。
然后将效果绑定到props.count
更改;
useEffect(() => {
console.log('I am JOKER\'s useEffect--->', props.count);
setCount(props.count);
}, [props.count]);// <-- This one
哪个在组件从组件DC获取新值时触发。它将自身Joker
的状态设置为props.count,这将导致组件重新呈现。
然后,您会得到以下输出:
I am JOKER's render--> 1 // Initial render where Joker receives props from DC
index.js:27 I am JOKER's useEffect---> 2 // The hook runs because props.count changed
index.js:27 I am JOKER's render--> 2 // Joker rerenders because its state updated.
答案 2 :(得分:0)
如果我们只想对componentShouldUpdate做同样的事情,则可以使用useMemo。
Traceback (most recent call last):
File "C:\Users\u532246\Envs\test\lib\site-packages\django\db\backends\oracle\base.py", line 47, in <module>
import cx_Oracle as Database
ModuleNotFoundError: No module named 'cx_Oracle'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "c:\users\u532246\appdata\local\programs\python\python38-32\Lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "c:\users\u532246\appdata\local\programs\python\python38-32\Lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\u532246\Envs\test\lib\site-packages\django\utils\autoreload.py", line 54, in wrapper
fn(*args, **kwargs)
File "C:\Users\u532246\Envs\test\lib\site-packages\django\core\management\commands\runserver.py", line 109, in inner_run
autoreload.raise_last_exception()
File "C:\Users\u532246\Envs\test\lib\site-packages\django\utils\autoreload.py", line 77, in raise_last_exception
raise _exception[1]
File "C:\Users\u532246\Envs\test\lib\site-packages\django\core\management\__init__.py", line 337, in execute
autoreload.check_errors(django.setup)()
File "C:\Users\u532246\Envs\test\lib\site-packages\django\utils\autoreload.py", line 54, in wrapper
fn(*args, **kwargs)
File "C:\Users\u532246\Envs\test\lib\site-packages\django\__init__.py", line 24, in setup
apps.populate(settings.INSTALLED_APPS)
File "C:\Users\u532246\Envs\test\lib\site-packages\django\apps\registry.py", line 114, in populate
app_config.import_models()
File "C:\Users\u532246\Envs\test\lib\site-packages\django\apps\config.py", line 211, in import_models
self.models_module = import_module(models_module_name)
File "C:\Users\u532246\Envs\test\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 783, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "C:\Users\u532246\Desktop\skripsi\Django-master\polls\models.py", line 6, in <module>
class Question(models.Model):
File "C:\Users\u532246\Envs\test\lib\site-packages\django\db\models\base.py", line 117, in __new__
new_class.add_to_class('_meta', Options(meta, app_label))
File "C:\Users\u532246\Envs\test\lib\site-packages\django\db\models\base.py", line 321, in add_to_class
value.contribute_to_class(cls, name)
File "C:\Users\u532246\Envs\test\lib\site-packages\django\db\models\options.py", line 204, in contribute_to_class
self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
File "C:\Users\u532246\Envs\test\lib\site-packages\django\db\__init__.py", line 28, in __getattr__
return getattr(connections[DEFAULT_DB_ALIAS], item)
File "C:\Users\u532246\Envs\test\lib\site-packages\django\db\utils.py", line 201, in __getitem__
backend = load_backend(db['ENGINE'])
File "C:\Users\u532246\Envs\test\lib\site-packages\django\db\utils.py", line 110, in load_backend
return import_module('%s.base' % backend_name)
File "C:\Users\u532246\Envs\test\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 783, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "C:\Users\u532246\Envs\test\lib\site-packages\django\db\backends\oracle\base.py", line 49, in <module>
raise ImproperlyConfigured("Error loading cx_Oracle module: %s" % e)
django.core.exceptions.ImproperlyConfigured: Error loading cx_Oracle module: No module named 'cx_Oracle'
单击按钮时,JOKER不会再次呈现。