如何将InputField组件的inputVal传递到App.js的fetch请求中?
如何将子组件的输入值传递给父组件并用于API请求?
核心需求:把InputField组件中用户输入的inputVal,替换到App组件fetch请求URL里的!!HERE!!位置,触发对应地址的token数据请求。
解决思路
React中父子组件通信,父组件通过传递回调函数给子组件,子组件在获取到输入值后调用这个回调,把值传给父组件;父组件用状态保存这个值,再根据这个值发起API请求。
修改步骤
1. 在App组件中添加状态存储输入值
在App组件里新增一个inputVal状态,用来保存从InputField传过来的地址:
function App() { const [tokens, setTokens] = useState([]) const [loading, setLoading] = useState(false) // 新增状态存储输入的地址 const [inputVal, setInputVal] = useState("") // ... 其他代码 }
2. 给InputField组件传递回调函数
修改App组件中调用InputField的方式,把setInputVal作为回调传过去(注意不要直接调用{InputField()},改用组件标签形式):
// 把原来的 {InputField()} 改成: <InputField onSubmit={setInputVal} />
3. 修改InputField组件,触发父组件的回调
在InputField组件里,接收父组件传的onSubmit属性,在表单提交时调用它,把inputVal传回去:
export default function InputField({ onSubmit }) { // 接收父组件的回调 function handleSubmit(e) { e.preventDefault(); const form = e.target; const inputVal = form.myInput.value; // 调用父组件的回调,传递输入值 onSubmit(inputVal); 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> ); }
4. 更新App组件的fetch逻辑
修改useEffect的依赖项为inputVal,并且只有当inputVal不为空时才发起请求,同时替换URL里的占位符:
useEffect(() => { // 输入值为空时不请求 if (!inputVal) return; setLoading(true) // 替换URL里的!!HERE!!为inputVal fetch(`https://api.multiversx.com/accounts/${inputVal}/tokens`) .then(response => response.json()) .then(json => setTokens(json)) .finally(() => { setLoading(false) }) }, [inputVal]) // 依赖inputVal,值变化时重新请求
另外,App组件里原来的{window.inputVal}可以改成{inputVal},直接用状态值显示。
修改后的完整代码
InputField.js
export default function InputField({ onSubmit }) { function handleSubmit(e) { e.preventDefault(); const form = e.target; const inputVal = form.myInput.value; onSubmit(inputVal); 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> ); }
App.js
import './App.css'; import AccountNumber from "./components/AccountNumber"; import InputField from "./components/InputField"; import { useEffect, useState } from "react" function App() { const [tokens, setTokens] = useState([]) const [loading, setLoading] = useState(false) const [inputVal, setInputVal] = useState("") useEffect(() => { if (!inputVal) return; setLoading(true) fetch(`https://api.multiversx.com/accounts/${inputVal}/tokens`) .then(response => response.json()) .then(json => setTokens(json)) .finally(() => { setLoading(false) }) }, [inputVal]) function round(nr, ten) { return Math.round(nr * ten) / ten; } function numberWithSpaces(nr) { 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 onSubmit={setInputVal} /> </div> <p>{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;
内容的提问来源于stack exchange,提问作者August 7337
相关产品推荐
相关产品推荐

