首页 > 解决方案 > 已经设置的反应挂钩如何设置为另一个值

问题描述

这是我第一次使用 React hooks,我偶然发现了一个我无法解决的问题。我正在使用formAmount钩子来获取将其存储在的输入值state.amount。发生这种情况时,只要用户将其放入,该数量就应该减少到一个数字。问题是我无法在该onChange事件中创建一个新数组,因为它会记录按键的每一次敲击并且它没有给我完整的数字,我不能直接在state.amount. 如何获得该数量并存储在数组中?

这是我的代码:

const Transactions = () => {
    const [state, setState] = useState([
        {
            expense: [],
            amount: [],
            id: ''
        }

    ])

    const [formExpense, setFormExpense] = useState('')
    const [formAmount, setFormAmount] = useState([])



    const handleSubmit = (e) => {
        e.preventDefault();

        addExpense()
        e.target.reset()
    }
    // add total of array of amount
    let sum = formAmount.reduce((accumulator, currentValue) => {
        { return accumulator += currentValue }
    }, 0)

    // push value of input to array
    const addExpense = (e) => {

        setState([...state, { expense: formExpense, amount: [...formAmount], id: Math.random() * 100 }])

    }


    return (
        <div className="transactions">

            <div className="expenses">
                <form onSubmit={handleSubmit}>
                    <input
                        type="text"
                        id="expense"
                        className="formfield"
                        name="expense"
                        placeholder="Expense..."
                        onChange={(e) => setFormExpense(e.target.value)}
                    />
                    <input
                        type="text"
                        id="amount"
                        className="formfield"
                        name="amount"
                        placeholder="Amount..."
                        onChange={(e) => setFormAmount([Number(e.target.value)])}
                    />
                    <button type="submit">Submit</button>
                </form>
            </div>
            <div className="finalbalance ">

                <div className="finalexpense final">
                    Total Expense
                    {'$' + sum.toLocaleString()}
                    {
                        state.map(stat => {
                            return (

                                <div key={stat.id}>

                                    <h3 className="outputexpense output">{stat.expense + stat.amount}</h3>
                                </div>


                            )
                        })
                    }

                </div>
            </div>
        </div>


    )
}

标签: javascriptreactjsreact-hooks

解决方案


这是给你的答案。我在这里也做了一个小提琴

function Transaction(props){

    const [listOfExpenses, setlistOfExpenses] = React.useState([]);
    const [expense, setExpense] = React.useState("");
    const [amount, setAmount] = React.useState(0);
    const [totalExpenditure, setTotalExpenditure] = React.useState(0);


    const handleInputChange = (hookSetterMethod) => (e) =>{
        let {value} = e.target;
        return hookSetterMethod(value);
    }

    const addExpense = (expenseObject) => {
        setlistOfExpenses([...listOfExpenses, expenseObject])
    }

    const getTotalExpenditure = (listOfExpenses) =>
    {
            if(listOfExpenses.length > 0)
        {
          let tempExpenseAmountList = listOfExpenses.map((expense, id)=>{
              if(expense.amount)
              {
                  return expense.amount;
              }else{
                  return 0;
              }
          });

          return tempExpenseAmountList.reduce((accumulator, currentVal)=>{
              return Number(accumulator) + Number(currentVal);
          })
        }
        return 0;
    }

    React.useEffect(()=>{
        setTotalExpenditure(getTotalExpenditure(listOfExpenses));
    }, [listOfExpenses])

    const handleFormSubmission = (e) =>{
        e.preventDefault();
        addExpense({
            amount,
            expense
        });
    }
    
    const renderExpenses = (expenseList) => {
      return expenseList.map((expense, id)=>{
        return (
          <tr key={id}>
            <td>{++id}</td>
            <td>{expense.expense}</td>
            <td>: ${expense.amount}</td>
          </tr>
        )
      });
    }

    return(
        <div>
            <div>
                <h1>Add your expenses below</h1>
                <form onSubmit={handleFormSubmission}>
                    <div>
                        <label>Expense</label>
                        <input value={expense} onChange={handleInputChange(setExpense)} />
                    </div>
                    <div>
                        <label>Amount</label>
                        <input value={amount} onChange={handleInputChange(setAmount)} />
                    </div>
                    <div>
                        <button type="submit">Add Expense</button>
                    </div>
                </form>
            </div>
            <hr />
            <div>
              <table>
                <tr>
                  <th>
                      <td>Id</td>
                      <td>Expense</td>
                      <td>Amount</td>
                  </th>
                </tr>
                {renderExpenses(listOfExpenses)}
                <tr className="total">
                  <td>Total Expenses</td>
                  <td>: ${totalExpenditure}</td>
                </tr>
              </table>
            </div>
        </div>
    );
}


ReactDOM.render(<Transaction />, 
document.getElementById("root"));
table{
  margin-top: 15px;
}

.total{
  display: table;
  border-top: 1px solid #434649;
  border-bottom: 2px double #434649;
  color: #f80000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>


推荐阅读