React hooks useEffect calls mutiple times when redux store other data changed

Viewed 348

my code like this:

Info component:

import {
 getAttachData,
} from '@src/actions/creators/account'
 
const Info: React.FC = () => {
  const info = useSelector<any, Account>(state => state.getIn(['account', 'info']).toJS())
  const list = useSelector<any, Data[]>(state => state.getIn(['account', 'list']).toJS())
  const attach = useSelector<any, AttachData[]>(state => state.getIn(['account', 'attach']).toJS())
  ...
  
  const handleChange = ({ select }) => {
    dispatch(getAttachData({v: select}))
  }
  
  const Template = (params) => {
    return (
     <div>
       <BaseSelect onChange={(val) => handleChange(val)} list={list} />}
     </div>
    )
  }
  
  return (
    ...
    <Template data={info} />
    {attach.map((child, cidx) => (<Template data={child} />))}
  )
}

export default Info

BaseSelect component:

const BaseSelect: React.FC<Props> = props => {
  const [selectId, setSelectId] = useState('')
  const { list } = props
  
  useEffect(() => {
    if (!isEmpty(list)) {
      ...
    }
    console.log('init')
  }, [])

  const handleChange = (value) => {
    setSelectId(value)
    
    props.onChange({
      select: value,
    })
  }
 
  return (
    <Select
      data={list}
      value={selectId}
      onChange={handleChange}
    />
  )
}

export default BaseSelect

when excute handleChange event in BaseSelect component, the props.onChange function will call handleChange event in info component, and dispatch http request getAttachData which will change attach data in redux store, but useEffect in BaseSelect component will also excute and in console will print 'init' two times.

console:

enter image description here

1 Answers

It's because your Template component re-creates every time when redux store is changing.

Just move Template component outside the Info component.

Related