简体   繁体   中英

How do components re-render in redux using hooks

I am trying to conceptualize redux and its working, and after some testing, I have noticed a thing. I would like to quote this example

lets say, I have a single reducer (a boolean variable). based on that variable, the following code happens.

reducer

const initState = { isLoggedIn: false };
const isLoggedInReducer = (state = initState, action) => {
  switch (action.type) {
    case "LOG_IN":
      return { ...state,isLoggedIn: true };
    case "LOG_OUT":
      return { ...state,isLoggedIn: false };
    default:
      return state;
  }
};

export default isLoggedInReducer;

action

export const logIn = () => {
    return {
        type:'LOG_IN'
    }
}

export const logOut = () => {
    return {
        type:'LOG_OUT'
    }
}

index.js

<Provider store={createStore(isLoggedInReducer)}>
      <Router>
        <Switch>
          <Route path="/" exact>
            <AppScreen />
          </Route>
          <Route path="/auth">
            <AuthScreen />
          </Route>
          <Route path="*">
            <NotFoundScreen />
          </Route>
        </Switch>
      </Router>
    </Provider>

so, my app firstly directs the user to a component called "mainScreen", which is as follows

const AppScreen = () => {
  let isLoggedIn = useSelector((state) => state.isLoggedIn);
  if (isLoggedIn)
    return (
      <>
          <button onClick={() => dispatch(logOut())}>unauthenticate</button>
          <NavBar />
          <Content />
          <BottomBar />
      </>
    );
  else{
    return (
      <>
        <Redirect to="/auth" push />
      </>
    );
  }
};

so if the reducer state has value TRUE, my navbar and stuff is shown, else the user is redirected to the "authScreen", which is as

const AuthScreen = () => {
  let isLoggedIn = useSelector((state) => state.isLoggedIn);
  const dispatch = useDispatch();
  return isLoggedIn ? (
    <>
        <Redirect to="/" push />
    </>
  ) : (
    <>
      <h1> auth is {isLoggedIn?"true":"false"}</h1>
      <button onClick={() => dispatch(logIn())}>authenticate</button>
    </>
  );
};

This creates a setup where "authScreen" can toggle the reducer to TRUE and it re-renders, and finds that reducer is TRUE, so it renders the "mainScreen". Vice versa for "MainScreen"

Now, what components actually re-render? If I place my authenticate button in the "navbar" instead as a sibling to "navbar", will it re-render the "navbar" or the "mainScreen"?

How does redux calculate what component to re-render when a peice of state changes? How does the useSelector fit in, when I did not even use "connect".

Using hooks with redux made it very confusing. I am sorry if my explanation is hard to understand. The code actually works, I just don't know how. Any piece of information is appreciated!

Using Redux with a UI always follows the same basic steps :

  • Render components using initial state
  • Call store.subscribe() to be notified when actions are dispatched
  • Call store.getState() to read the latest data
  • Diff old and new values needed by this component to see if anything actually changed. If not, the component doesn't need to do anything
  • Update UI with the latest data

React-Redux does that work for you internally.

So, useSelector decides whether a component should re-render based on whatever data you return in your selector functions:

https://redux.js.org/tutorials/fundamentals/part-5-ui-react#reading-state-from-the-store-with-useselector

If the selector return value changes after an action was dispatched, useSelector forces that component to re-render. From there, normal React rendering behavior kicks in, and all child components are re-rendered by default .

Please read my post The History and Implementation of React-Redux and talk A Deep Dive into React-Redux for details on how React-Redux actually implements this behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM