React项目API与用户输入合并存数组及map渲染异常问题
Axie Infinity React工具问题修复方案
核心问题原因
- 表单状态处理逻辑错误:直接操作数组类型的
dataAll状态存储表单输入,未正确调用状态更新方法,导致输入内容未实际存入状态 - 数据合并逻辑错误:提交请求后将用户输入数据、API返回钱包数据作为两个独立元素插入数组,导致两类数据分离
- 请求参数取值错误:从数组类型的
dataAll直接读取roninAddress字段,永远返回undefined,无法正确请求接口 - 类型错误:在表单输入处理中误将数组类型的
dataAll转为对象,后续调用map方法时触发类型错误
修复后完整代码
import React, { useState, useEffect } from 'react'; import { FormControl, Form, InputGroup, Button, Container, } from 'react-bootstrap'; import { nanoid } from 'nanoid'; import axios from 'axios'; import * as usertz from 'user-timezone'; const AxieAPI = () => { // 存储所有用户完整数据,初始为空数组 const [dataAll, setDataAll] = useState([]); // 新增表单输入状态,单独管理用户输入的内容 const [formInput, setFormInput] = useState({ myName: '', roninAddress: '' }); useEffect(() => { console.log(dataAll); }, [dataAll]); const onChangeHandler = (e) => { const fieldName = e.target.name; const fieldValue = e.target.value; // 更新表单状态 setFormInput(prev => ({ ...prev, [fieldName]: fieldValue })); }; const onSubmitHandler = async (e) => { e.preventDefault(); // 校验地址不为空 if(!formInput.roninAddress.trim()) return; // 请求参数移到提交函数内,获取最新的输入地址 const options = { method: 'GET', url: `https://axie-infinity.p.rapidapi.com/get-final-data/0x${formInput.roninAddress}`, params: { id: `0x${formInput.roninAddress}` }, headers: { 'x-rapidapi-host': process.env.REACT_APP_HOST, 'x-rapidapi-key': process.env.REACT_APP_KEY, }, }; try { const response = await axios.request(options); // 合并用户输入、API返回数据为同一个对象 const newUser = { id: nanoid(), myName: formInput.myName, roninAddress: formInput.roninAddress, walletData: response.data }; // 插入到用户数据数组 setDataAll(prev => [...prev, newUser]); // 提交后清空表单 setFormInput({myName: '', roninAddress: ''}); } catch (error) { console.error(error); } }; return ( <div> <Container className="p-5"> <Form onSubmit={onSubmitHandler}> <FormControl aria-label="Small" aria-describedby="inputGroup-sizing-sm" name="myName" value={formInput.myName} onChange={onChangeHandler} placeholder="输入自定义名称" /> <InputGroup className="mb-3"> <InputGroup.Text id="basic-addon1">ronin:</InputGroup.Text> <FormControl aria-label="Small" aria-describedby="inputGroup-sizing-sm" value={formInput.roninAddress} name="roninAddress" onChange={onChangeHandler} placeholder="输入ronin地址(不含ronin:前缀)" /> <Button type="submit">Add User</Button> </InputGroup> </Form> <div> {dataAll.map((singleData) => { const unixTimeStamp = singleData.walletData.next_claim_timestamp; const dateTimeFormat = 'MMMM Do, YYYY h:mm ss A'; const datetime = usertz.datetime(unixTimeStamp, dateTimeFormat); return ( <div key={singleData.id}> <p>User Name : {singleData.myName}</p> <p> Last Claim Amount : {singleData.walletData.last_claim_amount} </p> <p> Yesterday Earn SLP:{' '} {singleData.walletData.calendar.yesterdaySLP} </p> <p>Total SLP : {singleData.walletData.total_slp}</p> <p>Today Adv SLP ?/50: {singleData.walletData.adventureSLP}</p> <p>Rank : {singleData.walletData.pvpData.rank}</p> <p>MMR : {singleData.walletData.pvpData.elo}</p> <p>Next Claim : {datetime}</p> </div> ); })} </div> </Container> </div> ); }; export default AxieAPI;
内容的提问来源于stack exchange,提问作者longtech
相关产品推荐
相关产品推荐

