对于不影响渲染的变量,我应该使用state吗


  1. 在下面的代码中,如何使status变量的值在setStatus(!status)之后立即更改?我知道React中的状态更新是分批的,因此我使用带有回调的useEffect,但在第一次单击按钮时,status的值仍然记录为false(好像它没有立即更改(
  2. 考虑到应用程序渲染在任何方面都不依赖于status变量(实际上,我甚至更希望该变量的更改不会触发渲染(,完全不使用useEffect并将status设为"0"是不是一种糟糕的做法;正常的";变量,像status = true一样分配

function App() {
const [status, setStatus] = React.useState(false)
React.useEffect(() => toggleStatus, [status])
function onClickHandler() {
toggleStatus()
console.log(status)
}
function toggleStatus() {
setStatus(!status)
}
return ( 
<div>
<button onClick={onClickHandler}>Toggle & log status</button>
</div>
)
}
ReactDOM.render( < App /> , document.getElementById('root'))
<script src="https://unpkg.com/react@^16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.13.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
<div id="root"></div>

  1. 单击onClickHandler时触发===>toggleStatusconsole.log(status)是同步触发的(toggleStatus的setStatus(!status)是异步触发的。所以你可以看到false被记录了。并且您使用useEffect不正确。React.useEffect(() => toggleStatus, [status])表示useEffect返回toggleStatus函数的第一个自变量,即useEffect的清除动作

尝试此操作以查看记录的状态

React.useEffect(() =>{
//you can see true after first click here
console.log(status)
}, [status])
  1. 如果要立即更改status而不重新渲染组件,则应使用useRef

我会评论你的代码

function App() {
const [status, setStatus] = React.useState(false)
React.useEffect(() => toggleStatus, [status]) // here you are toggle the status again when the status change 
function onClickHandler() {
toggleStatus()
console.log(status)
}
function toggleStatus() {
setStatus(!status) // here you can do setStatus(prevStatus => !prevStatus)
}
return ( 
<div>
<button onClick={onClickHandler}>Toggle & log status</button>
</div>
)
}
ReactDOM.render( < App /> , document.getElementById('root'))
<script src="https://unpkg.com/react@^16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.13.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
<div id="root"></div>

你可以尝试在useEffect中使用console.log(状态(,看看是否一切正常。

React.useEffect(() => console.log(status), [status])

现在谈谈第二点,在我看来,这是一个不错的做法。根据React文档:

状态包含特定于此组件的数据,这些数据可能会更改随着时间的推移。[…]如果你不在render((中使用它,它就不应该在州。例如,您可以将计时器ID直接放在例子

React状态用于跟踪应用程序状态,并在底层状态发生变化时重新呈现应用程序。

现在,如果不希望重新渲染,则当status发生更改时,应将status声明为常规变量。

如果需要,您仍然可以使用useEffectreact钩子。您可以在这里初始化statususeEffect被称为组件安装/呈现在浏览器DOM 上

在下面的代码中,如何使状态变量的值在setStatus(!status)之后立即更改?

您不能立即更改状态,因为更改状态是异步的。

我甚至更希望这个变量的更改不会触发渲染(,完全不使用useEffect并将状态设为";正常的";变量,像status=true一样赋值?

首先,检查useEffect的用例是什么。

关于制作";正常的";相反,这确实是一种糟糕的做法:

const Component = () => {
let variable = ...;
return <>...</>
}

这是因为,在每次渲染时,这些变量都会被重新分配(因为在每次渲染中执行的函数组件的主体(通常,这不是所需的行为。

相反,您希望使用具有useRef的引用。查看useRef和变量之间的区别。

更改引用值不会触发渲染,因此不会更新UI。

最新更新