<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Geller MIcael</title>
    <description>The latest articles on Forem by Geller MIcael (@sleepytenor).</description>
    <link>https://forem.com/sleepytenor</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F599898%2F36368321-3537-4889-a330-ec3339805d2e.jpeg</url>
      <title>Forem: Geller MIcael</title>
      <link>https://forem.com/sleepytenor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sleepytenor"/>
    <language>en</language>
    <item>
      <title>Part 2: Building a Decentralized Exchange with Solidity and React</title>
      <dc:creator>Geller MIcael</dc:creator>
      <pubDate>Thu, 09 Jun 2022 05:03:26 +0000</pubDate>
      <link>https://forem.com/sleepytenor/part-2-building-a-decentralized-exchange-with-solidity-and-react-4g4p</link>
      <guid>https://forem.com/sleepytenor/part-2-building-a-decentralized-exchange-with-solidity-and-react-4g4p</guid>
      <description>&lt;p&gt;Welcome back &lt;strong&gt;frens&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://dev.to/sleepytenor/part-one-building-a-decentralized-exchange-with-solidity-and-react-2ne0"&gt;Part One&lt;/a&gt; we got to setting up our base project and our constructor function for the DEX. Today we'll be working on our first token swap function and exploring testing with hardhat.&lt;/p&gt;

&lt;p&gt;Here's a live &lt;a href="https://github.com/Geller99/DexterExchange.git"&gt;github repo&lt;/a&gt; of the project to keep-up with the article and video series.&lt;/p&gt;

&lt;p&gt;To understand more about PancakeRouter integration for this project, watch &lt;a href="https://www.youtube.com/watch?v=GXiSsJVc5V0"&gt;Gabi's breakdown&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  First Swap Function - $BNB
&lt;/h2&gt;

&lt;p&gt;In our very first function, we'll be allowing the user to send Binance native tokens $BNB to the smart contract for exchange, giving the Router permission to transact the token for the swap, performing the actual token swap and emitting an event which says "Hey! Just swapped my BNB for some select tokens!" &lt;/p&gt;

&lt;p&gt;First, we need to declare an event which will be emitted when token swaps are successfully complete…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;event SwapTransfer (address from, address to, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;but why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Turns out, events are Solidity's way of logging transaction details in smart contracts. Essentially, we declare an event that accepts certain parameters, and then we emit it in a function after a certain transaction has occurred. The event is basically an EVM dispatch signal we can listen to on the client side, with information about whatever transaction triggers it.&lt;/p&gt;

&lt;p&gt;Next, we declare our function body,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function swapExactBNBForTokens(uint amountOutMin, address tokenOut) external payable {
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;external?&lt;/strong&gt; this indicates a function that can only by called by external parties, and not within the same smart contract.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;payable?&lt;/strong&gt; this modifier is used to indicate that a function can transact (receive and send) within a contract. &lt;/p&gt;

&lt;p&gt;Inside this function, we'll declare a fixed-size array that holds two addresses. The first address being that of the token we are trading in, and the second address being that of the token we would be receiving in return.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function swapExactBNBForTokens(uint amountOutMin, address tokenOut) external payable {
address[] memory path = new address[](2);
path[0] = pancakeRouter.WETH();  // technically wrappedBNB
path(1) =  tokenOut;   // address of selected token on frontend
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we approve the &lt;code&gt;Router&lt;/code&gt; to transact our token so it can perform the swap. For this, we'll need a dependency, the IERC20 &lt;code&gt;approve()&lt;/code&gt; function which allows another &lt;code&gt;contract&lt;/code&gt; to transact &lt;code&gt;tokens&lt;/code&gt; for a &lt;code&gt;user&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's what the IERC20 approval function looks like&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;approve(address spender, uint265 amount);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Navigate to your terminal and install this dependency&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install @openzeppelin/contracts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then import this line at the top of your contract&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import "@openzeppelin/contracts/token/ERC20/IERC20.sol";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Back in our function, we'll implement this function using our Router&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IERC20(pancakeRouter.WETH()).approve(address(pancakeRouter), msg.value);
// technically wrappedBNB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line means, the "wrapped" token-$BNB is approving &lt;code&gt;pancakeRouter&lt;/code&gt; to transact a user provided amount of tokens . &lt;code&gt; msg.value&lt;/code&gt; represents the user inputted amount.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: WETH here means wrapped $ETH, but since we're on the Binance Smart Chain, it represents wrapped $BNB, the native token of BSC. &lt;br&gt;
Now we write the swap!&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pancakeRouter.swapExactETHForTokens{value: msg.value}(amountOutMin, path, msg.sender, block.timestamp + 60 * 10);

// technically its swapExactBNBForTokens
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We call the function in &lt;code&gt;pancakeRouter&lt;/code&gt; to swap our exact amount of BNB tokens for any other &lt;code&gt;token&lt;/code&gt; we want. Let's examine the interface of this function to understand the parameters it accepts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function swapExactETHForTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable returns (uint[] memory amounts);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the &lt;code&gt;amountOutMin&lt;/code&gt; represents the minimum amount of tokens sent back to the user.&lt;br&gt;
the &lt;code&gt;path&lt;/code&gt; array holds the addresses of both tokens being swapped.&lt;br&gt;
the &lt;code&gt;address&lt;/code&gt; to refers to the destination of the token after it's swapped.&lt;br&gt;
the &lt;code&gt;deadline&lt;/code&gt; is a specified time limit in which a transaction fails, to avoid long pending transactions and inaccurate prices.&lt;br&gt;
But holdon! There's a certain piece of syntax lost on us - &lt;code&gt;{value: msg.value}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This represents solidity's way of sending a &lt;code&gt;blockchain's&lt;/code&gt; native token to a &lt;code&gt;payable&lt;/code&gt; function. Without the &lt;code&gt;payable&lt;/code&gt; keyword, this transaction will revert. So this is how we send the user's BNB to the contract.&lt;/p&gt;
&lt;h2&gt;
  
  
  Moving On…
&lt;/h2&gt;

&lt;p&gt;The next thing we need to do is get the &lt;code&gt;amountsOut&lt;/code&gt; from the &lt;code&gt;router&lt;/code&gt;, we do so using an internal &lt;code&gt;pancakeRouter&lt;/code&gt; function that accepts the user's input, the &lt;code&gt;path&lt;/code&gt; array and returns two amounts -  the number of tokens sent in and number of &lt;code&gt;tokens&lt;/code&gt; sent back to the user.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;uint256[] memory amounts = pancakeRouter.getAmountsOut(msg.value, path);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We then log our token swap using the &lt;code&gt;emit&lt;/code&gt; keyword and passing arguments to the event we created earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;emit SwapTransfer(address(pancakeRouter), msg.sender, pancakeRouter.WETH(), tokenOut, msg.value, amounts[1]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Marvelous work! We've effectively sent BNB to our contract, approved the contract to transact our tokens, swapped the tokens and logged that transaction from the blockchain!&lt;/p&gt;

&lt;p&gt;Your function should look like this now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iuQVLqxF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r7lz6zpe6dmhkef1kyt2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iuQVLqxF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r7lz6zpe6dmhkef1kyt2.png" alt="Image description" width="880" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing our first Function with Hardhat and Moralis
&lt;/h2&gt;

&lt;p&gt;We're ready to test our function and see it in action. So head over to the folder named &lt;code&gt;tests&lt;/code&gt; in your project directory and open &lt;code&gt;sample.js&lt;/code&gt;. In there, you should find some sample test functions that come by default with a hardhat project. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SR691Mdu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9glw231391dwm54clcjm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SR691Mdu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9glw231391dwm54clcjm.png" alt="Image description" width="880" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll be changing the file name to &lt;code&gt;TestDexter.js&lt;/code&gt; and updating the function descriptions inside the describe block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
describe("Dex Testing", () =&amp;gt; {

  it("Should accept user's BNB and swap for Cake", async () =&amp;gt; { }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we'll setup our constants, including parameters for the swap function and then a &lt;code&gt;beforeEach&lt;/code&gt; method to deploy the smart contract so we can run the swap function.&lt;/p&gt;

&lt;p&gt;For our swap function, recall we need the contract address of both tokens.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Note -  in production, these token addresses are automatically fetched by the &lt;code&gt;DEX&lt;/code&gt; after user picks what token they wish to exchange for. But for the purpose of writing tests, we need to provide these addresses ourselves. *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Head over to &lt;a href="https://docs.pancakeswap.finance/code/smart-contracts/pancakeswap-exchange/router-v2"&gt;pancakeswap docs&lt;/a&gt; and copy the contract address for the PancakeRouter.&lt;/p&gt;

&lt;p&gt;And retrieve the contract address of the $cake token over &lt;a href="https://bscscan.com/token/0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Once you're done setting up constants, the next line you need is getting a &lt;code&gt;signer&lt;/code&gt; with ethers.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const accounts = await ethers.getSigners();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;owner = accounts[0]&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A Signer in Ethers.js is an object that represents an Ethereum account. It's used to send transactions to contracts and other accounts. Here we're getting a list of the accounts in the node we're connected to, which in this case is Hardhat Network, and only keeping the first/owner account for our test purposes - &lt;a href="https://hardhat.org/guides/waffle-testing"&gt;source is Hardhat documentation on testing&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next, we create a contract factory for any instances of our &lt;code&gt;exchange&lt;/code&gt; we need to deploy&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const DexterExchangeContract = await ethers.getContractFactory("DexterExchange");&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This line basically says, "from our smart contract, generate a factory and store in a variable" - this makes it easy to run tests on instances of the same smart contract. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;read up on the &lt;code&gt;factory&lt;/code&gt; pattern in OOP to gain more insight.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After creating the factory, we deploy the smart contract with &lt;code&gt;ethers&lt;/code&gt; and log the address of the &lt;code&gt;contract&lt;/code&gt; to the console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...

dexterExchange = await DexterExchangeContract.deploy(pancakeRouterAddress); 
await dexterExchange.deployed();
console.log(`dexterExchange deployed at ${dexterExchange.address}`);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the actual test block,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it("Should accept user's BNB and swap for Cake", async () =&amp;gt; {
     const bnb_cake_swap_tx = await dexterExchange.connect(owner).swapExactBNBForTokens
(0, 
cakeTokenAddress,
{value: ethers.utils.parseEther("500")});  
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code snippet gets the &lt;code&gt;connect&lt;/code&gt; method from our &lt;code&gt;exchange&lt;/code&gt; to connect the &lt;code&gt;owner&lt;/code&gt; to the contract, then tests the &lt;code&gt;swap&lt;/code&gt; function we wrote.&lt;/p&gt;

&lt;p&gt;For our function parameters, we will pass in zero as the&lt;code&gt;amountOutMin&lt;/code&gt; parameter, pass in the &lt;code&gt;cakeTokenAddress&lt;/code&gt; for the &lt;code&gt;tokenOut&lt;/code&gt; parameter and pass in the amount of tokens we wish to send to the contract using the &lt;code&gt;utils.parseEther&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;At this point, your entire test file should look like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T7V2PbYf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdijo1xhspvu4umpid8o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T7V2PbYf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdijo1xhspvu4umpid8o.png" alt="Image description" width="880" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Up Next: Setting up Hardhat Config
&lt;/h2&gt;

&lt;p&gt;Head over to your &lt;code&gt;hardhat.config.js&lt;/code&gt; file and replace the existing &lt;code&gt;module.exports&lt;/code&gt; object with this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
module.exports = {
  solidity: "0.8.4",
  networks: {
    hardhat: {
      chainId: 31337,
    },
    localhost: {
      url: "https://localhost:8545",
      chainId: 31337,
    },
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sets up our &lt;code&gt;hardhat&lt;/code&gt; local chain id and sets up localhost as the destination url for the forked version of the BSC mainnet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Forking Binance Smartchain Mainnet From Moralis
&lt;/h2&gt;

&lt;p&gt;Next, you want to head to &lt;a href="https://moralis.io/"&gt;moralis&lt;/a&gt;, create an account and head over to the admin dashboard. On the bottom-left side of the dashboard, click on "speedy nodes". This will give you a list of options.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6UzZJoQV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0xzuyqwwjv5pw77q8a4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6UzZJoQV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0xzuyqwwjv5pw77q8a4i.png" alt="Image description" width="880" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the Binance Smart Chain, click on the button that says endpoints and it should reveal a list of endpoints.&lt;/p&gt;

&lt;p&gt;Copy the url to the "mainnet archive", head back to your project terminal and enter the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat node --fork "paste mainnet archive url here"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will complete a fork of the BSC mainnet and you should see the following result in your terminal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eb_4GbY0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wg8n8o2x7h58zej3i706.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eb_4GbY0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wg8n8o2x7h58zej3i706.png" alt="Image description" width="880" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congrats! You now have a local running node of the Binance Smart Chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Local Blockchain in Metamask
&lt;/h2&gt;

&lt;p&gt;Now, we get to add our mainnet fork to Metamask so we can view changes in token amounts after running our test swaps.&lt;/p&gt;

&lt;p&gt;If you haven't already, head over to the &lt;a href="https://metamask.io/download/"&gt;download page&lt;/a&gt; and install metamask for your web browser of choice. Once you're done setting installing and setting up a wallet, head over to settings, click on &lt;code&gt;networks&lt;/code&gt; and hit &lt;code&gt;add network&lt;/code&gt;. This should open up the following page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hOBW9Cl9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6rivibdv8z7zska6ck6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hOBW9Cl9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6rivibdv8z7zska6ck6.png" alt="Image description" width="880" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the following details next...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rnc3T4fS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hsg7mwrh6fspn2m8m7eo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rnc3T4fS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hsg7mwrh6fspn2m8m7eo.png" alt="Image description" width="880" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You might encounter an error here since we entered the values AFTER running the node. To fix this, close your current running node in the terminal and run the command again&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat node --fork "paste mainnet archive url here"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then re-enter your chain id in the field and click  "save".&lt;/p&gt;

&lt;p&gt;Voila! Your own local binance chain is running and recognized by metamask. You should be able to see all your wallet information now with the currency $BNB.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_rU5hYvp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hi8a44zuj0fik6fvts7m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_rU5hYvp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hi8a44zuj0fik6fvts7m.png" alt="Image description" width="880" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Import a Wallet
&lt;/h2&gt;

&lt;p&gt;To import one of the available free accounts on the BSC localhost fork, right click on the account button in the metamask extension.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9QnAeZim--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68xej6do8q0zacidqr4r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9QnAeZim--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68xej6do8q0zacidqr4r.png" alt="Image description" width="880" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;head to the terminal in your project and copy the private key from the first account and paste in the 'private key' field.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3n77LjrW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e895wdr53oyse4n0996f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3n77LjrW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e895wdr53oyse4n0996f.png" alt="Image description" width="880" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Running our Tests
&lt;/h2&gt;

&lt;p&gt;Whew! Finally!&lt;/p&gt;

&lt;p&gt;To run your test function, type this command into the terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat test --network localhost

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all's well, this should be your result!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eCRMDGzO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mhfo7m5oy1cmh2gltxlf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eCRMDGzO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mhfo7m5oy1cmh2gltxlf.png" alt="Image description" width="880" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now head back to your metamask wallet and notice your native BNB balance is no longer 10,000 but now &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GJAu-_YO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7k1ezshskx75ly06572.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GJAu-_YO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7k1ezshskx75ly06572.png" alt="Image description" width="880" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait! Where's the token I swapped for? Where's my CAKE?!!!!!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Well...see, we lied...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;JK&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Turns out you need to &lt;strong&gt;import&lt;/strong&gt; a &lt;code&gt;token&lt;/code&gt; for your wallet to recognize it.&lt;/p&gt;

&lt;p&gt;So, on your wallet page, click "import token", head over to &lt;a href="https://coinmarketcap.com/currencies/pancakeswap/"&gt;coinmarketcap&lt;/a&gt; and copy the contract address for the $CAKE token.&lt;/p&gt;

&lt;p&gt;Paste it into your import form and it should automatically recognize the token.&lt;/p&gt;

&lt;p&gt;Great work! You've officially performed the sexiest token swap in DeFi history, on your own local smart chain. Here's my result!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GyYh9DSu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8jaeji6z3jt0uq4ajypx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GyYh9DSu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8jaeji6z3jt0uq4ajypx.png" alt="Image description" width="880" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ctt.ac/dlT6i"&gt;Tweet us about it!&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Rounding up - Next Lesson Preview
&lt;/h2&gt;

&lt;p&gt;Hey! I know this was a much longer lesson but you did amazing, if you have any questions or would simply like to keep up with the series, reach &lt;a href="https://twitter.com/elixir_js"&gt;myself&lt;/a&gt; or &lt;a href="https://twitter.com/GabiDev98"&gt;Gabi&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the next lesson, we'll be writing and testing more swap functions for various types of tokens and discussing advanced solidity patterns. Thanks for joining us!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>web3</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Part One: Building a Decentralized Exchange with Solidity and React</title>
      <dc:creator>Geller MIcael</dc:creator>
      <pubDate>Sun, 05 Jun 2022 20:16:36 +0000</pubDate>
      <link>https://forem.com/sleepytenor/part-one-building-a-decentralized-exchange-with-solidity-and-react-2ne0</link>
      <guid>https://forem.com/sleepytenor/part-one-building-a-decentralized-exchange-with-solidity-and-react-2ne0</guid>
      <description>&lt;p&gt;Hello Degens!&lt;/p&gt;

&lt;p&gt;Welcome to the birth of a new series, I'm super excited to take you through this marvelous project as we look to up our skills in full-stack web 3 engineering.&lt;/p&gt;

&lt;p&gt;This article-tutorial &lt;code&gt;series&lt;/code&gt; is built in partnership with &lt;code&gt;Gabi&lt;/code&gt;, AKA &lt;a href="https://www.youtube.com/channel/UCWNHq_VzBxC7NIQiXkVsyMQ"&gt;CleverBlocks &lt;/a&gt; on youtube, a Fullstack Engineer at Weave Financial. &lt;/p&gt;

&lt;p&gt;The video code content on his channel will be broken down more explicitly via these articles, as we seek to put more emphasis on the more complex topics in smart contract engineering. &lt;/p&gt;

&lt;p&gt;Before diving into build mode, let's have a brief overview of what &lt;code&gt;decentralized exchanges&lt;/code&gt; are and how they work. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is a DEX?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UVTe9NT9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h7e5m7zovwld4y6i2d1f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UVTe9NT9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h7e5m7zovwld4y6i2d1f.jpg" alt="DEX" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A decentralized exchange (DEX) is an automated medium for the user-driven exchange of digital tokens. The term &lt;code&gt;user-driven&lt;/code&gt; indicates a lack of intermediaries; meaning, users get to transact directly with each other and can do so without the need of a third-party such as a bank, broker, or other forms of centralized authority. &lt;/p&gt;

&lt;p&gt;Read more about DEXs here! &lt;a href="https://www.coindesk.com/learn/2021/08/20/what-is-an-automated-market-maker/"&gt;https://www.coindesk.com/learn/2021/08/20/what-is-an-automated-market-maker/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How does this all work?
&lt;/h2&gt;

&lt;p&gt;Well, DEXes are smart-contract powered; meaning, a piece of code living on the blockchain dictates the rules of these token swaps between users and automates transactions. On the back-end, users can also stake their funds as liquidity - meaning, &lt;strong&gt;&lt;em&gt;"Hey, I'll put my funds down as some sort of collateral for transactions, and in return, I earn a % return on these transactions"&lt;/em&gt;&lt;/strong&gt;. This entire structure creates a trustless ecosystem where digital assets can be securely and consistently transacted.&lt;/p&gt;

&lt;p&gt;A few examples of such exchanges are uniswap, sushiswap, pancakeswap, and apeswap. Each of these platforms runs on native blockchain code and features a large list of compatible tokens for swapping.&lt;/p&gt;

&lt;p&gt;As we get deeper in this series, we'll also detail the process of implementing liquidity pools and liquidity tokens, utilizing pancakeswap's Masterchef contract, and more! &lt;/p&gt;

&lt;p&gt;At the end of this series, we'll be covering a lot more than simple solidity; this course goes into implementing smart contract inheritance, reentrancy securities, testing with hardhat, forking the mainnet blockchain with moralis, integrating our local blockchain with MetaMask, and writing custom solidity with detailed explanations, patterns, and documentation on every feature we implement!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ready to get started? Let's get you all set up! &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Setting up a local development environment
&lt;/h2&gt;

&lt;p&gt;Head over to an IDE of your choice (I'll be using VSCode, which can be downloaded at "link"), open up a terminal, and type in the following command to initialize a project.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Following the prompts should generate a package.json file that contains information about your base project. After this, make your way to &lt;strong&gt;hardhat.org&lt;/strong&gt; to get started installing the hardhat suite.&lt;/p&gt;

&lt;p&gt;Copy the following command to your terminal &lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install - save-dev hardhat&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next, type in the following to run hardhat locally&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx hardhat&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command should present you with a short list of options, we'll stick with the first "Create a basic sample project" and hit enter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Following the remaining prompts should get you set up with a gitignore and a project root folder.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once you're done following the prompts and creating a hardhat project, we can get to importing &lt;code&gt;smart contract&lt;/code&gt; dependencies and setting up our contracts folder! &lt;/p&gt;

&lt;h2&gt;
  
  
  PancakeRouter? Why?
&lt;/h2&gt;

&lt;p&gt;The first dependency we need for our &lt;code&gt;DEX&lt;/code&gt; is a &lt;code&gt;Router&lt;/code&gt; contract. The router contains the core logic for swapping different &lt;code&gt;token&lt;/code&gt; types, adding and removing &lt;code&gt;liquidity&lt;/code&gt; , and functions that tell a user how many tokens they receive for their particular input amounts. It essentially acts as an &lt;code&gt;intermediary&lt;/code&gt; between the users and other smart contracts.  &lt;/p&gt;

&lt;p&gt;We'll be writing our function implementations based on the interface for the &lt;code&gt;PancakeRouter&lt;/code&gt; and connecting that to the pre-existing &lt;code&gt;PancakeRouter&lt;/code&gt; contract on the Binance Smart Chain.&lt;/p&gt;

&lt;p&gt;We'll also take a look at some transactions on the Binance Smart Chain to closely examine live examples of swap transactions.&lt;/p&gt;

&lt;p&gt;Go ahead and open this &lt;a href="https://github.com/pancakeswap/pancake-swap-periphery/tree/master/contracts/interfaces"&gt;link&lt;/a&gt; to view the different versions of &lt;code&gt;PancakeRouter&lt;/code&gt; available. &lt;/p&gt;

&lt;p&gt;For this series, we'll be using v1 and v2 as the base interfaces for our smart contracts. &lt;strong&gt;(learn how interfaces work in smart contracts here…)&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Copy the contents of the v1 and v2 files and put them into a single file in your local directory named &lt;code&gt;DexRouter.sol&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next, you should create a new file named &lt;code&gt;DexterExchange.sol&lt;/code&gt; and import the interfaces in &lt;code&gt;DexRouter.sol&lt;/code&gt;…at this point, your project should look like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yM_ySXsk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1kyjo4knmdy2m6j600bq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yM_ySXsk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1kyjo4knmdy2m6j600bq.png" alt="Project setup" width="880" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing Our Constructor
&lt;/h2&gt;

&lt;p&gt;Congrats! We've learned a lot today. But before we round up, we'll be putting down a few lines of code and explaining what they do.&lt;/p&gt;

&lt;p&gt;Navigate to your DexterExchange.sol and let's create our Router variable. This variable will be initialized to the address of PancakRouter currently active on the Binance Smart Chain. We'll be calling all the internal functions of the router via this variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
import './DexRouter.sol'

contract DexterExchange {

       // declare state variable of type PancakeRouter02 interface
       IPancakeRouter02 public pancakeRouter;

      // the pancakeRouter variable will hold all internal methods of any contract with its      address specified in the constructor 
       constructor(address _pancakeRouter) {
           pancakeRouter = IPancakeRouter02(_pancakeRouter);
       }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yQG9IUkb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x987yvz4ko4lzalb8ylz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yQG9IUkb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x987yvz4ko4lzalb8ylz.png" alt="Setting up constructor function" width="880" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice work! Now when we deploy DexterExchange, we'll pass in the address of pancakeRouter currently active on the Binance Smart Chain and run our Dex transactions with it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Remarks - Next Lesson Peek
&lt;/h2&gt;

&lt;p&gt;Thanks for joining us today! I truly hope you find this guide helpful for getting started on building a DEX. In the next session, we'll be writing a function to swap BNB for an exact amount of tokens provided by the user. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We'll dive deep into payable functions, the IERC20 dependency, sending tokens to a contract, and granting our pancakeRouter permissions to transact tokens sent to payable functions. We'll also cover testing our first function with hardhat, forking the binance smart chain mainnet with Hardhat, and setting up our local chain with Metamask!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're looking to get ahead of the class, check out Gabi's &lt;a href="https://www.youtube.com/watch?v=yqNiu8ezwvk"&gt;Youtube&lt;/a&gt; for more videos on this course. &lt;/p&gt;

&lt;p&gt;Catch up with &lt;a href="https://twitter.com/GabiDev98"&gt;Gabi&lt;/a&gt; and &lt;a href="https://twitter.com/Elixir_Js"&gt;Me&lt;/a&gt; on Twitter for weekly solidity code review and request to join our dev discord!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>web3</category>
      <category>react</category>
    </item>
    <item>
      <title>What’s the 101? the useState Hook in React</title>
      <dc:creator>Geller MIcael</dc:creator>
      <pubDate>Sat, 19 Feb 2022 10:34:31 +0000</pubDate>
      <link>https://forem.com/sleepytenor/whats-the-101-the-usestate-hook-in-react-47pl</link>
      <guid>https://forem.com/sleepytenor/whats-the-101-the-usestate-hook-in-react-47pl</guid>
      <description>&lt;p&gt;My mentor always told me, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“for every new concept you learn, there's three major whys”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Why does it work this way? why do we have to use it this way? why was it created? And in this junior dev thriller, I’ll be attempting to answer these questions about the useState hook in React.&lt;/p&gt;

&lt;p&gt;To understand the purpose of hooks, we need to shed some light on React’s core principle — Rendering efficiency. The major difference between React’s behavior and Vanilla JavaScript is it’s interaction with the browser DOM. React implements a virtual DOM which interfaces with the real DOM tree to ensure an efficient updating process. Check for props and state changes in every component, update the DOM with observed changes, leave unchanged components the same(memoize).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the useState Hook?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The react way of storing the application state and updating the view elements. React simplifies storing and managing information about our application via the useState hook. This ensures the state is persisted within the component and updated with each re-render — a behavior we term statefulness!&lt;/p&gt;

&lt;p&gt;How do we use it?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VZYNptHZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hm0u6dfedwy3p6kymu4j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VZYNptHZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hm0u6dfedwy3p6kymu4j.png" alt="useState Hook" width="880" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We start with destructuring the hook and setting a name for our variable and its setter method. Then we provide a default value to our variable on the right-hand side of the assignment operator.&lt;/p&gt;

&lt;p&gt;This immediately gives us access to reading and updating our state via the returned variable and setter method.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;How does React opt to reason about it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;“Well, let’s see…I need a way to SAFELY store and update information about my app, make that information local to the component it’s created in, then make sure it triggers a component re-render at the right time”.&lt;/p&gt;

&lt;p&gt;React only lets us modify the state variable via a setter method, which ensures state values cannot be randomly reassigned or mutated without the setter method provided at declaration.&lt;/p&gt;

&lt;p&gt;let’s take a look…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gfZq13qb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nm3wid0xlxk8u5mvzky6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gfZq13qb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nm3wid0xlxk8u5mvzky6.png" alt="protected state" width="880" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How was it designed?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To truly understand things, I end up needing to rebuild them myself. Examining the implementation of hooks outside the browser should make better sense of what’s going on under the hood.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EnbPxIyE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/996g51gqjjhabqqh8rtm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnbPxIyE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/996g51gqjjhabqqh8rtm.png" alt="useState in Nodejs" width="880" height="707"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Understanding stateful behavior&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A core and often unexplained principle in software engineering is “state” and the derivative word “stateful”.&lt;/p&gt;

&lt;p&gt;Statefulness refers to storing interactions and using the data in future interactions. Often, we need to implement operations that rely on data from a previous operation; so we store the data in “state” and update it with every new interaction.&lt;/p&gt;

&lt;p&gt;In React, we enable this behavior at the component level via the useState hook.&lt;/p&gt;

&lt;p&gt;Statefulness also ensures a “protected state”; meaning functions now have internal variables that can only be accessed within them and are “preserved” with every new call to that method. React hooks implements a protected state by providing a setter method as the only access point to the internal state.&lt;/p&gt;

&lt;p&gt;In vanilla JavaScript, this behavior is enabled via “closures” (a more advanced topic I won’t be diving into here) — &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;useState vs normal variable declarations&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“why implement a separate way to manage local state? why don’t we just use regular variables like in Vanilla JavaScript? What’s the trade-off?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In all fairness, we can use regular variable declarations within React, but the general rule of thumb is, “if it directly affects the view layer, hook into statefulness”.&lt;/p&gt;

&lt;p&gt;This is because changes to state trigger re-renders in the view components, but changes in regular variables only change locations in memory, meaning relying on regular variables to handle the view-state will result in our application being out of sync.&lt;/p&gt;

&lt;p&gt;Another reason is, with each call to the component and resulting re-render, there is an “update” to state — meaning values are “preserved within function calls, while for regular variable declarations, there is a “reset” to the initial value.&lt;/p&gt;

&lt;p&gt;here’s an example&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EnirKT7Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zrb4u4hpc5mxo7bf26tz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnirKT7Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zrb4u4hpc5mxo7bf26tz.png" alt="State vs Local Variables" width="880" height="504"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“When should I use the useState hook? when do we favor local variables instead? can it be used to implement global state?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;use Case #1 -&amp;gt; Parent-Child props&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When passing state as props from parent to child components, we declare the state values in the parent component using the useState hook.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V8ehTaoS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0c0c9qt4qxqe1pnrqf9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V8ehTaoS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0c0c9qt4qxqe1pnrqf9x.png" alt="Parent-child props" width="880" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;use Case #2 -&amp;gt; Internal Component State&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When we need to create state that is bound to specific components in the view, we use the useState hook.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vCw9f2rZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jnmy8rwo7f0rpgr5qx69.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vCw9f2rZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jnmy8rwo7f0rpgr5qx69.png" alt="Internal State" width="880" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;use Case #3 -&amp;gt; Custom Hooks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When we need to create local state variables for custom hooks, we can use the useState hook too!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6fsKoiiK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9frm44h0y931up5rgto.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6fsKoiiK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9frm44h0y931up5rgto.png" alt="Custom Hooks" width="880" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;use Case #4 -&amp;gt; Context Providers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When we need to create state values and pass them into a Global context object, we use a store component with internal useState variables and pass that as the value to the context provider.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sR0_8Q6C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/49wtxxiwonknzmlmvaou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sR0_8Q6C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/49wtxxiwonknzmlmvaou.png" alt="Context Provider" width="880" height="821"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;use Case #5 -&amp;gt; Lazy Loading&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Load it when I need it!"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A performance optimization concept which lets us initialize expensive pieces of state only when the user is ready to consume it. Lazy-loading can be observed when reading through most news feeds; you notice images and long blocks of text only load-in as you scroll through. &lt;/p&gt;

&lt;p&gt;Here's an example of implementing lazy-loading for a counter variable. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WpthWnas--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c1qtk5f8557bqfq6whh0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WpthWnas--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c1qtk5f8557bqfq6whh0.png" alt="Lazy-Loading" width="880" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;use Case #6 -&amp;gt; Grabbing Previous State&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A super interesting part of the useState hook is how it gives us access to previous values of state when needing to perform operations on the current state!. We implement this by using a callback within the setter method.&lt;/p&gt;

&lt;p&gt;My example will be the famous toggle pattern.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xb9iI83M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2qfnbqpkuiukd1fnuryv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xb9iI83M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2qfnbqpkuiukd1fnuryv.png" alt="Previous State" width="880" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We initialize state to false, then the useState setter method let's us reference that initial value of state within a callback, which we use to determine the next state value. Pretty neat!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Non-use Case -&amp;gt; Accepting Parent props&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A general rule of thumb is, when data is derived from props (parent components passing data to children), we use local variables to store said data. The reason is, changes to props from the parent component will trigger re-renders in the child component and state changes also trigger re-renders. We need to avoid unnecessary re-renders and only store data in state when it isn’t reliant on parent components.&lt;/p&gt;

&lt;p&gt;I hope this article helped you gain some insights on the workings of the useState hook in React…here’s to curtains on this little deep-dive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;As always, I’m super open to correction and critique so let’s get educative conversations going!&lt;/em&gt;&lt;/strong&gt;``&lt;/p&gt;

&lt;p&gt;Feel free to contact me for more delightful conversations about React!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/elixir_js"&gt;https://twitter.com/elixir_js&lt;/a&gt;&lt;br&gt;
via email -&amp;gt; &lt;a href="mailto:Gellera800@gmail.com"&gt;Gellera800@gmail.com&lt;/a&gt;&lt;br&gt;
github -&amp;gt; Github.com/Geller99&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Continuous improvement and a steady diet of growth</title>
      <dc:creator>Geller MIcael</dc:creator>
      <pubDate>Sat, 30 Oct 2021 15:22:21 +0000</pubDate>
      <link>https://forem.com/sleepytenor/continuous-improvement-and-a-steady-diet-of-growth-3c8o</link>
      <guid>https://forem.com/sleepytenor/continuous-improvement-and-a-steady-diet-of-growth-3c8o</guid>
      <description>&lt;p&gt;Hello Devs,&lt;/p&gt;

&lt;p&gt;I'm currently looking to pool opinions and suggestions on an Saas platform I've been building, I'll be linking the repo and twitter channel at the end of this for those who wish to keep in touch.&lt;/p&gt;

&lt;p&gt;A year ago, I stumbled across a picture which said, if you grew/learned or added to your knowledge base by one percent every day for a year, you'd make 30%+ progress. Now, even without ever verifying the math, I quickly understood the underlying message. Being good consistently is the ONLY sure fire recipe for greatness.&lt;/p&gt;

&lt;p&gt;Following this path, I decided on tracking my growth over a year, making a daily snippet (day snip) and learning in public via my dev twitter (@Elixir_js).&lt;/p&gt;

&lt;p&gt;Turns out, I made well over 30% growth in the last year in my field (UI engineering), secured a solid internship and successfully built a  freelance client list to boot.&lt;/p&gt;

&lt;p&gt;With this theme in mind, and my personal success story; I started building onePercent (twitter @on3Percent). A platform based on repetitive, public accountability. &lt;/p&gt;

&lt;p&gt;The primary goal being to solve the problem of procrastination, along with building a public profile for yourself and your journey -  a public journal of some sort.&lt;/p&gt;

&lt;p&gt;Users contribute to a universal feed by creating daily accounts of what they've learned - each user gets one post a day; listing technology, topic, code snippet and a brief explanation of what they learned that day -  accounting for their daily one percent.&lt;/p&gt;

&lt;p&gt;The feed is public, other users can like, comment and share(outside) these short snippets or give accountability points. &lt;/p&gt;

&lt;p&gt;Beyond solving procrastination, this platform also solves the problem of documentation for people who cannot blog about their experiences or have no affinity for technical writing - giving everyone a chance to be heard and noticed, and held accountable as they grow. Every week, your notes are compiled into a progress node and emailed to you...creating a form of personalized spaced repetition and giving you a sense of progression and achievement going into the next week.&lt;/p&gt;

&lt;p&gt;At the moment, we're looking into more features and looking to hire QA engineers, a couple frontend engineers and a product manager to handle new features before official launch.&lt;/p&gt;

&lt;p&gt;I'd love to hear your thoughts on this project and if this is something you'd love to add to your daily process(creating daily submissions of what you've learned), or be a part of.&lt;/p&gt;

&lt;p&gt;The plan is to go open source in the near future, and make publicized modules for short contract roles to aid junior engineers in gaining paid experience while contributing to a project for the community.&lt;/p&gt;

&lt;p&gt;Feel free to ask any questions to gain more insight about the features and suggest anything else you'd like to see added.&lt;/p&gt;

&lt;p&gt;read more about continuous improvement here - &lt;a href="https://jamesclear.com/continuous-improvement"&gt;https://jamesclear.com/continuous-improvement&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
