Home > Enterprise >  React Hooks -Redux Saga Middleware
React Hooks -Redux Saga Middleware

Time:12-25

I am creating a React application with Saga middleware. And I have few doubts to clarify.

  • On the first mount, why is it we are destructing an unknown prop const { onGetPhonesAndTablets } = props which is not passed from the Redux Store (State Container).

  • Why is it required to setPhoneAndTabletsList(phonesAndTablets) before dispatching an action onGetPhonesAndTablets . As the prop phonesAndTablets will have its value after dispatching an action i.e., onGetPhonesAndTablets

const Home = props => {
  
  const { 
    phonesAndTablets
  } = props
  
  const [phonesAndTabletsList, setPhoneAndTabletsList] = useState([]);

  useEffect(() => {
    const { 
      onGetPhonesAndTablets
    } = props
    setPhoneAndTabletsList(phonesAndTablets)
    onGetPhonesAndTablets()
  }, [])

  useEffect(() => {
    if (!isEmpty(phonesAndTablets)) setPhoneAndTabletsList(phonesAndTablets)
  }, [phonesAndTablets])

  return (
    <React.Fragment>
        <ProductCategoryList list={phonesAndTabletsList}/>
    </React.Fragment>
  )
}

Home.propTypes = {
  phonesAndTablets: PropTypes.array,
  onGetPhonesAndTablets : PropTypes.func
}

const mapStateToProps = ({ home }) => ({
  phonesAndTablets: home.phonesAndTablets
})

const mapDispatchToProps = dispatch => ({
  onGetPhonesAndTablets: () => dispatch(getPhoneAndTablets())
})
export default connect(mapStateToProps, mapDispatchToProps)(Home)

CodePudding user response:

I'm not entirely sure why this app uses a local state to store the redux state, which is passed as a prop. Seems redundant, not to mention bad for performance.

There is a selector hook, which lets components access individual pieces of redux state. useSelector(state => state.home.phonesAndTablets).

You can also pass a second argument, shallowEqual, which makes the comparison function do a value comparison, as opposed to reference comparison. This avoids unnecessary re-renders due to objects/arrays whose contents are equal, but whose references point to different objects. Remember that ['a'] !== ['a'] in JS.

There is also a dispatch hook to do the same for actions. useDispatch(action). Then you can do

const list = useSelector(state => state.home.phonesAndTablets, shallowEqual)
const dispatch = useDispatch()

useEffect(() => {
  dispatch(getPhoneAndTablets())
}, [])

return (
  <>
      <ProductCategoryList list={list ?? []} />
  </>
)

I would personally add a check if the list is empty before fetching a new list, but maybe the app is supposed to fetch a new list whenever Home is mounted. I have no idea.

CodePudding user response:

Since, the above code seems redundant as the state is already managed and handled by the State Container (Redux Store). So I tried removing redundant codes.

Personally I prefer mapStateToProps to selectors.

const Home = props => {
  
  const { 
    phonesAndTablets, 
    onGetPhonesAndTablets
  } = props

  useEffect(() => {
    onGetPhonesAndTablets()
  }, [])

  return (
    <React.Fragment>
        <ProductCategoryList list={phonesAndTablets ? phonesAndTablets : ''}/>
    </React.Fragment>
  )
}

Home.propTypes = {
  phonesAndTablets: PropTypes.array,
  onGetPhonesAndTablets : PropTypes.func
}

const mapStateToProps = ({ home }) => ({
  phonesAndTablets: home.phonesAndTablets
})

const mapDispatchToProps = dispatch => ({
  onGetPhonesAndTablets: () => dispatch(getPhoneAndTablets())
})

export default connect(mapStateToProps, mapDispatchToProps)(Home)
  • Related