javascripthtmlreactjsfrontend

How to get variable from component for put on the App.js


Even by searching on the internet I did not find, or in all that I did not understand.

My problem: I would like the "inputVal" variable found in the InputField.js component to be found where there is "!!HERE!!" in the App.js component(on the fetch).

Please help me - thank you for reading my message!

export default function InputField() {
  
  function handleSubmit(e) {
    // Prevent the browser from reloading the page
    e.preventDefault();

    // Read the form data
    const form = e.target;
    const inputVal = form.myInput.value;

    console.log(inputVal);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <input name="myInput" id="adress-field" placeholder="Enter adress" autoComplete="on" />
      <button type="submit" id="adress-button">Send</button>
    </form>
  );
}
import './App.css';
import AccountNumber from "./components/AccountNumber";
import InputField from "./components/InputField";
import { useEffect, useState } from "react"

function App() {

  //token fetch
  const [tokens, setTokens] = useState([])
  const [loading, setLoading] = useState(false)
  useEffect(() => {
    setLoading(true)
    fetch("https://api.multiversx.com/accounts/!!HERE!!/tokens")
      .then(response => response.json())
      .then(json => setTokens(json))
      .finally(() => {
        setLoading(false)
      })
      console.log(tokens); 
  }, [])


  function round(nr, ten) { // arondi un chiffre.
    return Math.round(nr * ten) / ten;
}

function numberWithSpaces(nr) { // formate un chiffre(x xxx xxx).
    return nr.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
}



  return (
    <content className="content">
        <div className="up-side">
            <div className="account-number-box">
                <p id="p-account-number">Total number of accounts</p>
                <p id="account-number"><AccountNumber/></p>
            </div>
            <div className="adress-search">
                {InputField()}
            </div>
            <p>{window.inputVal}</p>
        </div>
        <div className="down-side">
            <table className="Token-section-output">
            

              {loading ? (
                <div>Loading...</div>
              ) : (
                <>
                  <h1>Tokens</h1>
                  <table className='Token-section-output' border={0}>
                    <tr className='token-row-type'>
                      <th className='token-column'>Name</th>
                      <th className='center-column'>Price</th>
                      <th>Hold</th>
                    </tr>
                    <tr className="space20"/>

                    
                    {tokens.map(token => (
                      <tr className='token-row' key={token.id}>
                        <td className='token-column'>
                        <img className="img-Tokens" src = {token?.assets?.pngUrl ?? "img/Question.png"} /> 
                          <p>{token.name}</p> 
                        </td>

                        <td className='center-column'> <p>${round(token.price, 10000000)}</p> </td>

                        <td> 
                          <p>{round(token.balance / Math.pow(10, token.decimals), 10000000)}</p> 
                          <p className='token-hold'>${round(token.valueUsd, 10000000)}</p>
                        </td>
                      </tr>
                    ))}

                  </table>
                </>
              )}


            </table>
        </div>   
    </content>
  );
}

export default App;

I not very good in react and i mak search on internet


Solution

  • You want to extend your InputField component to accept a callback function, that can be passed by your app:

    export default function InputField({onSubmit}) {
      
      function handleSubmit(e) {
        // Prevent the browser from reloading the page
        e.preventDefault();
    
        // Read the form data
        const form = e.target;
        const inputVal = form.myInput.value;
    
        console.log(inputVal);
        onSubmit(inputVal)
      }
    
      ...
    }
    

    And in your App you need to pass that callback to your component:

    <div className="adress-search">
      <InputField onSubmit={handleSearchSubmit} />
    </div>
    

    Note: Components are not consumed by calling them like functions.

    In your App logic, you'll need another state to hold your search value:

    ...
    const [searchValue, setSearchValue] = useState(null);
    
    const handleSearchSubmit = (val) => {
      setSearchValue(val);
    }
    
    useEffect(() => {
        setLoading(true)
        fetch(`https://api.multiversx.com/accounts/${searchValue}/tokens`)
          .then(response => response.json())
          .then(json => setTokens(json))
          .finally(() => {
            setLoading(false)
          });
        console.log(tokens); 
    }, [searchValue])
    ...