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 } = propswhich is not passed from the Redux Store (State Container).Why is it required to
setPhoneAndTabletsList(phonesAndTablets)before dispatching an actiononGetPhonesAndTablets. As the propphonesAndTabletswill 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)
