Javascript 我可以将多个useEffect重构为单个useEffect吗?

Javascript 我可以将多个useEffect重构为单个useEffect吗?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我的宽度状态随窗口大小的改变而改变,而showFilters作为道具的宽度状态则由真变假。我想在卸载时删除侦听器。因此,我对每个条件使用了三个useState。 那么,我能做些什么重构来在single useEffect中使用所有这些 import React, { useEffect, useRef, useState } from 'react' import PropTypes from 'prop-types' import { Icon } from 'antd' import Tr

我的宽度状态随窗口大小的改变而改变,而showFilters作为道具的宽度状态则由真变假。我想在卸载时删除侦听器。因此,我对每个条件使用了三个useState。 那么,我能做些什么重构来在single useEffect中使用所有这些

import React, { useEffect, useRef, useState } from 'react'
import PropTypes from 'prop-types'
import { Icon } from 'antd'

import TrendsChart from './trendsChart'

import styled from '../styled-components'

const Chart = ({ showFilters }) => {
  const [width, setWidth] = useState(null)
  useEffect(() => {
    window.addEventListener('resize', handleWindowResize)
    updateWidth()
  }, [width])
  useEffect(() => {
    setTimeout(updateWidth, 200)
  }, [showFilters])
  useEffect(() => () => {
    window.removeEventListener('resize', handleWindowResize)
  })
  const updateWidth = () => {
    const containerWidth = chartRef.current.clientWidth
    setWidth(Math.floor(containerWidth))
  }
  const handleWindowResize = () => {
    updateWidth()
  }
  const chartRef = useRef()
  function render() {
    return (
      <styled.chart>
        <styled.chartHeader>
          Daily
        </styled.chartHeader>
        <styled.trendsChart id="chartRef" ref={chartRef}>
          <TrendsChart width={width} showFilters={showFilters}/>
        </styled.trendsChart>
        <div>
          <Icon type="dash" />&nbsp;&nbsp;&nbsp;Credit Trend
        </div>
      </styled.chart>
    )
  }
  return (
    render()
  )
}

Chart.propTypes = {
  showFilters: PropTypes.bool.isRequired
}
export default Chart
import React,{useffect,useRef,useState}来自“React”
从“道具类型”导入道具类型
从“antd”导入{Icon}
从“/TrendsChart”导入TrendsChart
从“../styled components”导入样式
常量图表=({showFilters})=>{
常量[width,setWidth]=useState(null)
useffect(()=>{
window.addEventListener('resize',handleIndowerSize)
updateWidth()
},[宽度])
useffect(()=>{
设置超时(更新宽度,200)
},[showFilters])
使用效果(()=>()=>{
window.removeEventListener('resize',handleIndowerSize)
})
常量updateWidth=()=>{
const containerWidth=chartRef.current.clientWidth
设置宽度(数学地板(集装箱宽度))
}
常量HandleIndowerSize=()=>{
updateWidth()
}
常量chartRef=useRef()
函数render(){
返回(
每日的
信贷趋势
)
}
返回(
render()
)
}
Chart.propTypes={
showFilters:PropTypes.bool.isRequired
}
导出默认图表
据我所知 可以合并两个useEffect

useEffect(() => {
window.addEventListener('resize',handleWindowResize)
return () => window.removeEventListener('resize',handleWindowResize)
},[width])

对于设置超时部分,据我所知。这是不需要的,因为每次宽度(状态)更改时,react都将重新启动。希望对你有帮助。我也不太会反应。

你应该看看每种效果起作用的条件

侦听器应安装一次,并进行清理:

useEffect(() => {
  window.addEventListener('resize',handleWindowResize)
  return () => window.removeEventListener('resize',handleWindowResize)
},[])

const handleWindowResize = () => {
  const containerWidth = chartRef.current.clientWidth
  setWidth(Math.floor(containerWidth))
}
注意:
[]
作为
useffect
参数,如果没有此效果,则在每个渲染上都有效

。。。这就足够了,因为:

  • handleIndowerSize
    设置窗口大小更改时的宽度
  • showFilters
    自动导致重新加载

你能重构吗?是的,你可以。你应该重构吗?不,问题是,为什么?为什么您希望这样做?钩子的整个要点是只“订阅”/“侦听”您想要的依赖项(道具)。因此,保持它们的小而简洁。唯一可以重构的是
removeEventListener
钩子,而不是从添加事件侦听器的
useffect
中返回函数。这将在卸载时调用。这称为“清理效果”: