Javascript 在初始渲染时调用useEffect钩子而不更改依赖项

Javascript 在初始渲染时调用useEffect钩子而不更改依赖项,javascript,reactjs,react-hooks,state,Javascript,Reactjs,React Hooks,State,好吧,我正在经历一些我不太理解的行为。 我有这个国家钩子 const[permanent,setPermanent]=useState(false) 这是一个有用的钩子 useffect(()=>{ if(永久性){ 分派({值:'永久展位',键:'期间'}) }否则{ 分派({value:'0',key:'period'}) } }[永久]) 它会在初始渲染时触发重新渲染,在渲染我的组件时,我不会调用setPermanent,我已经通过注释应用程序中的每个setPermanent调用来检查

好吧,我正在经历一些我不太理解的行为。 我有这个国家钩子

const[permanent,setPermanent]=useState(false)
这是一个有用的钩子

useffect(()=>{
if(永久性){
分派({值:'永久展位',键:'期间'})
}否则{
分派({value:'0',key:'period'})
}
}[永久])
它会在初始渲染时触发重新渲染,在渲染我的组件时,我不会调用
setPermanent
,我已经通过注释应用程序中的每个
setPermanent
调用来检查这两个问题。我还尝试用一个登录到控制台的函数替换它

//const[permanent,setPermanent]=useState(false)
常量永久=假
常量setPermanent=()=>{
console.log('I am called')//在初始呈现时未被调用
}
我知道它会触发一个重读程序,因为当我将第二个调度调用中的一个注释掉时,它不会触发重读程序

useffect(()=>{
if(永久性){
分派({值:'永久展位',键:'期间'})
}否则{
//分派({value:'0',key:'period'})
}
}[永久])
是否有这样的原因,因为我似乎找不到解释这种行为的文档

编辑--------------

const shoppoptions=(()=>{
常量选项=[
{标签:'Choose a shop',值:'0'},
]
Object.keys(stores).forEach(store=>{
options[options.length]={label:store,value:options.length}
})
返回选项
})()
常数性别选项=[
{标签:'选择性别',值:'0'},
{标签:'Female',值:'1'},
{标签:'Male',值:'2'}
]
常量周期选项=[
{label:'选择一个句点',值:'0'},
{标签:“1周”,值:“1'},
{标签:'2周',值:'2'},
{标签:'3周',值:'3'},
{标签:'4周',值:'4'}
]
常量初始状态={
商店:商店选项[0],
性别:性别选项[0],
句点:句点选项[0],
}
函数缩减器(prevState,{value,key}){
const updateElement={…prevState[key]}
updateElement.value=值
返回{…prevState[key]:updateElement}
}
//形式
const[state,dispatch]=useReducer(reducer,initialState)

useffect
钩子在第一次渲染之后和每次更新传递到依赖项数组的变量之后都会运行(在您的例子中是
[permanent]

因为您有一个触发效果的布尔值,所以很难知道它是效果中的第一次渲染还是重新渲染。在这种情况下,我会考虑不使用<代码>使用效果<代码>,而是在更新状态时调度您需要的内容。例如:

const [permanent, setPermanent] = useState(false)

const makePermanent = () => {
  setPermanent(true)
  dispatch({ value: 'Permanent booth', key: 'period' })
}

const makeTemporary = () => {
  setPermanent(false)
  dispatch({ value: '0', key: 'period' })
}

useffect
钩子在第一次渲染之后和每次更新传递到依赖项数组的变量之后都会运行(在您的例子中是
[永久性]

因为您有一个触发效果的布尔值,所以很难知道它是效果中的第一次渲染还是重新渲染。在这种情况下,我会考虑不使用<代码>使用效果<代码>,而是在更新状态时调度您需要的内容。例如:

const [permanent, setPermanent] = useState(false)

const makePermanent = () => {
  setPermanent(true)
  dispatch({ value: 'Permanent booth', key: 'period' })
}

const makeTemporary = () => {
  setPermanent(false)
  dispatch({ value: '0', key: 'period' })
}

这是我的解决方案。只需一个布尔属性和排序挂钩就可以完成这项工作

const\u isMounted=React.useRef(false)
const[filter,setFilter]=React.useState(“”)
React.useffect(()=>{
如果(_isMounted.current){
getData(filter)//现在不会第一次调用它
}
},[过滤器])
/*秩序很重要。[]或所谓的componentDidMount()将是最后一个*/
React.useffect(()=>{
_isMounted.current=true
return()=>{
_isMounted.current=false
}
}, [])

这是我的解决方案。只需一个布尔属性和排序挂钩就可以完成这项工作

const\u isMounted=React.useRef(false)
const[filter,setFilter]=React.useState(“”)
React.useffect(()=>{
如果(_isMounted.current){
getData(filter)//现在不会第一次调用它
}
},[过滤器])
/*秩序很重要。[]或所谓的componentDidMount()将是最后一个*/
React.useffect(()=>{
_isMounted.current=true
return()=>{
_isMounted.current=false
}
}, [])

调度是否会导致组件卸载和重新装载?(例如,家长进入加载状态)。您可以返回一个cleanup函数,该函数只将某些内容记录到控制台,并在其中设置一个断点,以查看此时发生的情况。(由于组件和React呈现过程之间的抽象层和解耦,这并不像听起来那么简单。)调度是否会导致组件卸载和重新装载?(例如,家长进入加载状态)。您可以返回一个cleanup函数,该函数只将某些内容记录到控制台,并在其中设置一个断点,以查看此时发生的情况。(由于抽象层和组件与React渲染过程之间的解耦,这并不像听起来那么简单。)我不知道初始渲染时运行了所有useEffect挂钩,是否有办法防止这种情况?我刚刚意识到我的整个应用程序都有useEffects,这实际上解释了很多。componentDidUpdate没有真正的替代品吗?@JonasGrønbek这提供了一种模仿componentDidUpdate的方法,但我强烈建议不要经常这样做。这(非常全面)使我反对试图复制类生命周期方法。祝你好运我不知道所有的useEffect钩子在初始渲染时都运行过,难道没有办法阻止它吗