ReactJS |为什么在输入更改时更新此状态挂钩会清除输入以防止写入任何内容?

我正在尝试创建一个简单的表单,它接受两个字符串,将它们存储在状态挂钩中,并清除自身 onSubmit,但似乎是通过输入的 onChange 更新状态挂钩(即 { {1}}) 具有清除刚刚输入的内容的效果,导致字段不可用。当这一行被移除时,输入保留了数据,但当然,它不再存储在状态钩子中。

我的理解是/是通过相应的 setter 方法更新状态挂钩不会产生副作用,尽管这里似乎并非如此。不过,在一个更简单的测试应用程序中,事情按预期工作。可以在 https://zzimm.com/https://zzimm.com/admin 处(在发布时)看到这种行为。

我认为相关的代码部分

钩子:

onChange={(t) => setUserSide(t.target.value)}

表格:

const [newWager,setWager] = useState(0);
const [userSide,setUserSide] = useState(0);     

提交:

const Home = () => {
    return(
      <div classname="main">
      <div classname="upper">
      1: {retrievedSide1} : {potFor} WC<br/> 2: {retrievedSide2} : {potAgainst} WC
      </div>
      <div classname="card">
        <form classname="form" id="submitWagerForm" autocomplete="off" onSubmit={wager}>
          <label>
            Enter your wager and side:
            <br />
            <input
              classname="input"
              type="text"
              name="amount"
              placeholder="# of WC"
              onChange={(t) => setWager(t.target.value)}
            />
            <input
              classname="input"
              type="text"
              name="side"
              placeholder="1 or 2"
              onChange={(t) => setUserSide(t.target.value)}
            />
          </label>
          <button classname="button" type="submit" value="Submit">
            Submit
          </button>
        </form>

App.js 的其余部分

从完整的应用程序中剥离出来,但仍然表现出有问题的行为

const wager = async (t) => {
    t.preventDefault(); 
    try{
      const accounts = await window.ethereum.enable();
      const account = accounts[0];
      const _wager = web3.utils.toWei(newWager);

      const gas = await eventWagerContract.methods.wager(userSide,_wager).estimateGas();
      const post = await eventWagerContract.methods.wager(userSide,_wager).send({ from: account,gas });
      getUserWager(t);
      getcurrentPot(t);
    }
    catch(e)
    {
      alert('Apparently this is the best way to display blockchain errors :/\n\n' + e.message);
    }
    var form = document.getElementById("submitWagerForm");
    form.reset();
  };

更简单的测试应用

import logo from './logo.svg';
import React,{ useState } from "react";
import './App.css';
import { eventWager } from './abi/abi';
import { token } from './abi/abi';
import Web3 from "web3";
import { BrowserRouter as Router,Route,Switch } from 'react-router-dom';

const web3 = new Web3(Web3.givenProvider);
const contractAddress = "0x73A6Da02A8876C3E01017fB960C912dA0a423817";
const tokenAddress = "0x02F682030814F5AE7B1b3d69E8202d5870DF933f";
const eventWagerContract = new web3.eth.Contract(eventWager,contractAddress);
const tokenContract = new web3.eth.Contract(token,tokenAddress);

function App() {
  // Getter hooks
  const [retrievedWager,setRetrievedWager] = useState(0);
  const [currentPot,setRetrievedCurrentPot] = useState(0);
  const [potFor,setPotFor] = useState(0);
  const [potAgainst,setPotAgainst] = useState(0);
  const [retrievedUserSide,setRetrievedUserSide] = useState(0);
  const [retrievedSide1,setRetrievedSide1] = useState("1");
  const [retrievedSide2,setRetrievedSide2] = useState("2");
  const [requestAddress,setRequestAddress] = useState(0);
  const [requestAmount,setRequestAmount] = useState(0);

  // Setter hooks
  const [newWager,setWager] = useState(0);
  const [userSide,setUserSide] = useState(0);
  const [winningSide,setWinningSide] = useState(0);

  // Getter methods
  const getUserWager = async (t) => {
    if(t) { t.preventDefault(); }
    const accounts = await window.ethereum.enable();
    const account = accounts[0];
    const post = await eventWagerContract.methods.getWager(account).call();
    const _wager = web3.utils.fromWei(post);
    setRetrievedWager(_wager);
  };

  const getcurrentPot = async (t) => {
    if(t) { t.preventDefault(); }
    const post = await eventWagerContract.methods.getPot().call();
    const _pot = web3.utils.fromWei(post);
    setRetrievedCurrentPot(_pot);
  };
  
  // Setter methods
  const wager = async (t) => {
    t.preventDefault(); 
    try{
      const accounts = await window.ethereum.enable();
      const account = accounts[0];
      const _wager = web3.utils.toWei(newWager);

      const gas = await eventWagerContract.methods.wager(userSide,gas });
      getUserWager(t);
      getcurrentPot(t);
    }
    catch(e)
    {
      alert('Apparently this is the best way to display blockchain errors :/\n\n' + e.message);
    }
    var form = document.getElementById("submitWagerForm");
    form.reset();
  };

  const allowSpend = async (t) => {
    t.preventDefault();
    try{
      const accounts = await window.ethereum.enable();
      const account = accounts[0];
      const gas = tokenContract.methods.approve(contractAddress,web3.utils.toWei('9999')).estimateGas();
      const post = tokenContract.methods.approve(contractAddress,web3.utils.toWei('9999')).send({ from: account });
    }
    catch(e)
    {
      alert('Apparently this is the best way to display blockchain errors :/\n\n' + e.message);
    }
  };

  const getcurrentSides = async (t) => {
    if(t) { t.preventDefault(); }
    const post = await eventWagerContract.methods.getSides().call();
    // const post = await eventWagerContract.methods.getPot().call();
    var substrings = post.split('||&&||');
    setRetrievedSide1(substrings[0]);
    setRetrievedSide2(substrings[1]);
  };

  const Home = () => {
    return(
      <div classname="main">
      <div classname="upper">
      1: {retrievedSide1} : {potFor} WC<br/> 2: {retrievedSide2} : {potAgainst} WC
      </div>
      <div classname="card">
        <form classname="form" id="submitWagerForm" autocomplete="off" onSubmit={wager}>
          <label>
            Enter your wager and side:
            <br />
            <input
              classname="input"
              type="text"
              name="amount"
              placeholder="# of WC"
              onChange={(t) => setWager(t.target.value)}
            />
            <input
              classname="input"
              type="text"
              name="side"
              placeholder="1 or 2"
              onChange={(t) => setUserSide(t.target.value)}
            />
          </label>
          <button classname="button" type="submit" value="Submit">
            Submit
          </button>
        </form>
        <br />
        <div>
          <button classname="button" onClick={getUserWager} type="button">
            Your current wager: 
          </button>
            {retrievedWager}
        </div>
        <br /> <br />
        <div>
          <button classname="button" onClick={getcurrentPot} type="button">
            Click for current pot
          </button>
          {currentPot}
        </div>
        <br /><br />
        <div>
          <button classname="button" onClick={allowSpend} type="button">
              Click to approve
          </button>
        </div>
      <div classname="lower">
        <form classname="form" onSubmit={getcurrentSides}>
          <label>
              <button classname="button" type="submit" value="Submit">
                Get Sides
              </button>
            </label>
          </form>
        </div>
      </div>
    </div>
    );
  }

  return (
    <Router>
      <Switch>
        <Route exact path="/">
          <Home />
        </Route>
        <Route exact path="/admin">
          {/* <Admin /> */}
        </Route>
      </Switch>
    </Router>
  );
}

export default App;
wenjin666666 回答:ReactJS |为什么在输入更改时更新此状态挂钩会清除输入以防止写入任何内容?

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/638.html

大家都在问