Should I use useselector/useDispatch instead of mapStateToProps

后端 未结 5 1394
孤街浪徒
孤街浪徒 2021-02-19 00:07
5条回答
  •  庸人自扰
    2021-02-19 00:29

    Redux store state can be read and changed from anywhere in the component, including callbacks. Whenever the store state is changed the component rerenders. When the component rerenders, useSelector runs again, and gives you the updated data, later to be used wherever you want. Here is an example of that and a usage of useDispatch inside a callback (after an assignment in the root level):

    function Modal({ children }) {
      const isOpen = useSelector(state => state.isOpen);
      const dispatch = useDispatch();
      function handleModalToggeled() {
        // using updated data from store state in a callback
        if(isOpen) {
          // writing to state, leading to a rerender
          dispatch({type: "CLOSE_MODAL"});
          return;
        }
        // writing to state, leading to a rerender
        dispatch({type: "OPEN_MODAL"});
      }
      // using updated data from store state in render
      return (isOpen ? (
          
    {children}
    ) : ( ); ); }

    There is nothing you can do with mapStateToProps/mapDispatchToProps that you can't do with the useSelector and useDispatch hooks as well.

    With that said, there are a couple of differences between the two methods that are worth considering:

    1. Decoupling: with mapStateToProps, container logic (the way store data is injected into the component) is separate from the view logic (component rendering). useSelector represents a new and different way of thinking about connected components, arguing that the decoupling is more important between components, and that components are self contained. Which is better? Verdict: no clear winner. source
    2. DX (Developer experience): using the connect function usually means there should be another additional container component for each connected component, where using the useSelector and useDispatch hooks is quite strait forward. Verdict: hooks have better DX.
    3. "Stale props" and "Zombie child": there are some weird edge cases with useSelector, if it depends on props, where useSelector can runs before the newest updated props come in. These are mostly rare and avoidable edge cases, but they had been already worked out in the older connect version. verdict: connect is slightly more stable than hooks. source
    4. Performance optimizations: both support performance optimizations in different ways. connect has some advanced techniques, using merge props and other options hidden in the connect function. useSelector accepts a second argument - an equality function to determine if the state has changed. verdict: both are great for performance in advanced situations.
    5. Types: using typescript with connect is a nightmare. I remember myself feverishly writing three props interfaces for each connected component (OwnProps, StateProps, DispatchProps). Redux hooks support types in a rather straight forward way. verdict: types are significantly easier to work with using hooks.
    6. The future of React: Hooks are the future of react. This may seam like an odd argument, but change to the eco system is right around the corner with "Concurrent mode" and "Server components". While class components will still be supported in future React versions, new features may rely solely on hooks. This change will of course also affect third party libraries in the eco system, such as React-Redux. verdict: hooks are more future proof.

    TL;DR - Final verdict: each method has its merits. Connect is more mature, has less potential for weird bugs and edge cases, and has better separation of concerns. Hooks are easier to read and write, as they are collocated near the place where they are used (all in one self contained component). Also, they are easier to use with TypeScript. Finally, they will easily be upgradable for future react versions.

提交回复
热议问题