You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Have you been asked questions like this during interviews?:
Why react hook cannot be written in conditional or loop statements?
(This is a classic question of Chinese style interview, we call it '八股文', which basically means that the questions is too classic and everyone can answer it by remembering it)
In this article, we will learn the software engineering principles behind the scenes. After learning these principles, you will easily understand how other state management tools(redux, jotal) work.
The Rules of Hooks
Don’t call Hooks inside loops, conditions, or nested functions
Learning How React Hooks Work by Building a Naive useState
Part 1: What is a State?
A state is nothing more than a getter and a setter.
You can see the concept of state exists in almost all programming languages. (Some programming languages use stream instead given that the issues state causes)
It is a powerful abstraction given that we ordinarily view the world as populated by independent objects, each of which has a state that changes over time.
An object is said to "have state" if its behavior is influenced by its history.
Let's take an example using Javascript:
Say, we wanna build a bank account system. Whether we can withdraw a certain amount of money from a bank account depends upon the history of deposit and withdrawal transactions.
functionbankAccount(deposit){letbalance=deposit;return(amount)=>{// check amount history and decide whether to withdrawif(balance>=amount){balance-=amount;returntrue;}returnfalse;}}constwithdraw=bankAccount(666);// success, balance is 111 now.withdraw(555);// failedwithdraw(666);
As you can see, in javascript, the state is pretty simple:
init: use keyword let to define a state let balance = 50;
setter: use = to assign(set) a new value to state balance = 666;
getter: use the variable name to get the value balance
Part 2: Implement useState
Once you understand the essence of state, you can easily understand react state too.
React state is nothing but a state abstraction with a rerender mechanism in react component.
I will walk through how to build a useState step by step. Before that, let's sort out what features we need to react state.
init: init a state, in react useState() init a state in a component.
getter: the first value of return array of useState() is the getter.
setter: the second value of return array of useState() is the setter.
rerender: when set a new state, it should trigger react component rerender using the latest state.
// init a state balance with value 666// get state using balance// set state using setBalance methodconst[balance,setBalance]=useState(666);Javascriptalreadyprovidesastateabstraction,andreactprovidesafunctionrendertorerenderacomponent.Let's build our useState upon these abstraction.let state;function useState(initialValue) { state = state || initialValue; function setter(newState) { state = newState; render(<App />, document.getElementById('root'));
}
return [state, setter];
}
Now it works pretty well! But as our react component becomes more complex, we find that this implementation is not sophisticated enough, it will break when there are multiple states are declared.
This is because we only store states in a single variable. Now we change it to Array(List), we need a cursor to indicate the index of the current state, so that we can get the correct state:
letstate=[];letcursor=0;functionuseState(initialValue){// get current cursor by orderconstcurrentCursor=cursor;state[currentCursor]=state[currentCursor]||initialValue;// assign next cursor to next useStatecursor++;functionsetter(newState){state[currentCursor]=newState;// reset cursorcursor=0;render(<App/>,document.getElementById('root'));}return[state[currentCursor],setter];}
Now let's take a look at what happens when we call the code below:
const[balance,setBalance]=useState(666);// state = [666], cursor = 1// balance = state[0]// setBalance = (newState) => state[0] = newState //...const[name,setName]=useState('handsome');// state = [666, 'handsome'], cursor = 2// name = state[1]// setBalance = (newState) => state[1] = newState //...// When we call setter:setBalance(777);// state = [777, 'handsome'], cursor = 0, rerender
Why is Order Important?
As you can see, the order is very important because we use array and index to help useState to map to correct state's getter and setter.
Let's take a look if we write hook inside a conditional statement:
letfirstRender=true;if(balance==='666'){const[balance,setBalance]=useState(666);firstRender=false;}const[name,setName]=useState('handsome');setBalance(777);Firstrender,theifstatementistrue,itexecutesasprevious:
const[balance,setBalance]=useState(666);// state = [666], cursor = 1// balance = state[0]// setBalance = (newState) => state[0] = newState //...const[name,setName]=useState('handsome');// state = [666, 'handsome'], cursor = 2// name = state[1]// setBalance = (newState) => state[1] = newState //...AftersetBalanceiscalled,ifbecomefalseandrerender:
// When we call setter:setBalance(777);// state = [777, 'handsome'], cursor = 0, rerenderconst[balance,setBalance]=useState(666);// state = [666], cursor = 1// balance = state[0]// setBalance = (newState) => state[0] = newState //...const[name,setName]=useState('handsome');// state = [666, 'handsome'], cursor = 1// name = state[0]// setBalance = (newState) => state[0] = newState //...
As you can see, the name state is mapped to the wrong state using the wrong cursor. This is why we cannot break the order of state execution using conditional or loop statements in react.
The text was updated successfully, but these errors were encountered:
An Interview Question
Have you been asked questions like this during interviews?:
(This is a classic question of Chinese style interview, we call it '八股文', which basically means that the questions is too classic and everyone can answer it by remembering it)
In this article, we will learn the software engineering principles behind the scenes. After learning these principles, you will easily understand how other state management tools(redux, jotal) work.
The Rules of Hooks
loops
,conditions
, ornested
functionsLearning How React Hooks Work by Building a Naive useState
Part 1: What is a State?
You can see the concept of
state
exists in almost all programming languages. (Some programming languages usestream
instead given that the issues state causes)Let's take an example using Javascript:
Say, we wanna build a bank account system. Whether we can withdraw a certain amount of money from a bank account depends upon the history of deposit and withdrawal transactions.
As you can see, in javascript, the state is pretty simple:
init
: use keyword let to define a statelet balance = 50;
setter
: use = to assign(set) a new value to statebalance = 666;
getter
: use the variable name to get the valuebalance
Part 2: Implement useState
Once you understand the essence of state, you can easily understand react state too.
I will walk through how to build a
useState
step by step. Before that, let's sort out what features we need to react state.init
: init a state, in reactuseState()
init a state in a component.getter
: the first value of return array ofuseState()
is thegetter
.setter
: the second value of return array ofuseState()
is thesetter
.rerender
: when set a new state, it should trigger react componentrerender
using the latest state.Here is how we use our state:
Now it works pretty well! But as our react component becomes more complex, we find that this implementation is not sophisticated enough, it will break when there are multiple states are declared.
Multiple States
It breaks when we add a name state:
This is because we only store
states
in a single variable. Now we change it toArray(List)
, we need acursor
to indicate the index of the current state, so that we can get the correct state:Now let's take a look at what happens when we call the code below:
Why is Order Important?
As you can see, the order is very important because we use array and index to help
useState
to map to correct state's getter and setter.Let's take a look if we write
hook
inside a conditional statement:As you can see, the
name
state is mapped to the wrong state using the wrongcursor
. This is why we cannot break the order of state execution using conditional or loop statements in react.The text was updated successfully, but these errors were encountered: