【问题标题】:How to update other fields based on a field value in forms of React Native?如何根据 React Native 表单中的字段值更新其他字段?
【发布时间】:2021-06-01 08:54:59
【问题描述】:

我有 4 个输入字段,如下所示。 名称、数量、数量、价格。 还有两个文本字段,佣金和总计。

如果用户按价格输入值并计数,则应计算金额(价格 * 计数)。 如果用户以价格和金额输入值,则应计算计数(金额/价格)。 在这两种情况下,commission=0.02*amount 和 total=amount+commission 都应该更新。

所以,我尝试使用下面的代码 sn-p 作为根据价格更新金额和佣金的开始。 但它没有更新。

//App.js

import React from "react";
import App1 from "./src/screens/createCoin.jsx";
import * as Font from "expo-font";

export default function App() {
  return <App1 />;
}

//createCoins.jsx

import React, { Component, useState } from "react";
import {
  Container,
  Header,
  Content,
  H1,
  Text,
  Form,
  Item,
  Input,
} from "native-base";

export default function createCoins() {
  const [name, setName] = useState("");
  const [price, setPrice] = useState("");
  const [amount, setAmount] = useState("");
  const [commission, setCommission] = useState("");
  const [count, setCount] = useState("");

  updateDetails = (text, type) => {
    console.log("came to update Details...");
    if (type === "price") {
      const price = parseFloat(text);
      setPrice(price);
      setAmount(price * count);
      setCommission(amount * 0.002);
    }
  };

  return (
    <Container>
      <Header />
      <Content>
        <Form>
          <Item>
            <Input
              placeholder="coin name"
              onChangeText={(text) => setName(text)}
            />
          </Item>
          <Item>
            <Input
              placeholder="number of coins"
              onChangeText={(text) => setCount(count)}
            />
          </Item>
          <Item>
            <Input
              placeholder="Amount Invested"
              onChangeText={(text) => setAmount(amount)}
            />
          </Item>

          <Item last>
            <Input
              placeholder="coin price"
              onChangeText={(text) => updateDetails(text, "price")}
            />
          </Item>
        </Form>
        <Text>Commission: {commission}</Text>
        <Text>Total Amount: {commission + amount}</Text>
      </Content>
    </Container>
  );
}

你能建议一下吗?

修改 createCoin.jsx 的代码如下。文本字段“总金额”正在更新,但如何更新输入字段金额?我尝试向它添加属性 value={state.amount} 但没有像无效道具一样出现错误。

import React, { Component, useState } from "react";
import {
  Container,
  Header,
  Content,
  H1,
  Text,
  Form,
  Item,
  Input,
} from "native-base";

export default function createCoins() {
  const [name, setName] = useState("");
  //const [price, setPrice] = useState("");
  //const [amount, setAmount] = useState("");
  //const [commission, setCommission] = useState("");
  //const [count, setCount] = useState("");
  const [state, setState] = useState({
    price: 0,
    amount: 0,
    commission: 0,
    count: 0,
  });

  /*const updatePrice = (value) => {
    console.log("came to update Details...");
    if (count) {
      setPrice(value);
      setAmount(value * count);
    }
  };*/

  updateDetails = (text, type) => {
    console.log("came to update Details...");
    if (type == "count") {
      setState({
        ...state,
        count: text,
      });
    }
    if (type === "price") {
      console.log("came inside price");
      const price = parseFloat(text);
      setState({
        ...state,
        price: price,
        amount: price * state.count,
        commission: state.price * state.count * 0.002,
      });
      //setPrice(price);
      //setAmount(price * count);
      //setCommission(amount * 0.002);
      console.log("price:" + price);
      console.log(state.amount);
      console.log(state.commission);
    }
  };

  return (
    <Container>
      <Header />
      <Content>
        <Form>
          <Item>
            <Input
              placeholder="coin name"
              onChangeText={(text) => setName(text)}
            />
          </Item>
          <Item>
            <Input
              placeholder="number of coins"
              onChangeText={(text) => updateDetails(text, "count")}
            />
          </Item>
          <Item>
            <Input
              placeholder="Amount Invested"
              value={state.amount}
              onChangeText={(text) => updateDetails(text, "amount")}
            />
          </Item>

          <Item last>
            <Input
              placeholder="coin price"
              onChangeText={(text) => updateDetails(text, "price")}
            />
          </Item>
        </Form>
        <Text>Commission: {state.commission}</Text>
        <Text>Total Amount: {state.commission + state.amount}</Text>
      </Content>
    </Container>
  );
}

【问题讨论】:

  • 我很乐意提供帮助,但我很难让原生基础运行
  • 好的,所以安装新版本对我来说几乎是不可能的,但回到 2.13 工作
  • 您的更改将对象作为状态,但是您每次都需要设置完整的对象。您应该像以前一样将您的值保留为单独的状态变量

标签: javascript react-native react-native-tools


【解决方案1】:

这就是我所做的

import React, { Component, useState, useEffect, useRef } from "react";
import {
  Container,
  Header,
  Content,
  H1,
  Text,
  Form,
  Item,
  Input,
} from "native-base";

export default function createCoins() {
  const [name, setName] = useState("");
  const [amount, setAmount] = useState("");
  const [count, setCount] = useState("");
  const [price, setPrice] = useState("");
  const [commission, setCommission] = useState("");
  // used to regulate when calculations are made
  const [ focusedInput, setFocus ] = useState(null)

  // run an effect when price, count, or amount changes
  useEffect(()=>{
    // if price and count exist and user isnt changing amount, calculate amount
    if(price && count && focusedInput !== 'amount'){
      setAmount( price * count );
    }
    // if price and count exist and user isnt changing count, calculate count
    else if(price && amount && focusedInput !== 'count'){
      setCount( amount / price )
    }
  },[price,count,amount])
  // when amount changes, update commission and total
  useEffect(()=>{
    if(isNaN(amount))
      setCommission('')
    if(amount)
      setCommission( amount * 0.002);
  },[amount])
  
  return (
    <Container>
      <Header />
      <Content>
        <Form>
          <Item>
            <Input
              placeholder="coin name"
              onChangeText={setName}
              keyboardType="decimal-pad"
            />
          </Item>
          <Item>
            <Input
              placeholder="number of coins"
              onChangeText={text => setCount(parseFloat(text))}
              keyboardType="decimal-pad"
              value={count.toString()}
              onFocus={()=>setFocus("count")}
            />
          </Item>
          <Item>
            <Input
              placeholder="Amount Invested"
              onChangeText={text => setAmount(parseFloat(text))}
              keyboardType="decimal-pad"
              value={amount.toString()}
              onFocus={()=>setFocus("amount")}
            />
          </Item>

          <Item last>
            <Input
              placeholder="coin price"
              onChangeText={text=>setPrice(parseFloat(text))}
              keyboardType="decimal-pad"
              value={price.toString()}
              onFocus={()=>setFocus("price")}

            />
          </Item>
        </Form>
        <Text>Commission: {commission}</Text>
        <Text>Total Amount: {commission +amount}</Text>
      </Content>
    </Container>
  );
}

focusedInput 的存在是为了防止在焦点(被更改)时自动计算一个值。如果没有focusedInput 条件,如果存在pricecountamount,则第三个值将从这两个值派生,即使您尝试更改第三个值也是如此。

例如,如果您在priceamount 存在时尝试编辑count 文本输入字段,则count 文本字段将在您输入下一个字符之前被setCount(amount/price) 覆盖。

通过在自动计算字段值之前验证字段不在焦点上,可以避免这种不良影响

【讨论】:

    【解决方案2】:

    您需要有单独的函数来根据输入值进行计算,例如

    const updatePrice = (value) => {
      if (count) {
        setPrice(value);
        setAmount(value * count);
        setCommission(value * count * 0.02); // do not use amount here directly as it is only calculated in the next render cycle
      }
    }
    

    在您的输入字段中,您将 onChange-Method 更改为 onChangeText={updatePrice}

    顺便说一句,您可以删除(text) =&gt; 作为onChangeText的签名(参数),方法是相同的。否则,您将在每个渲染上创建该函数的实例。这是为了性能/内存优化。

    【讨论】:

    • 我treid这个,但仍然没有更新。我的代码与您的更改:codeshare.io/2jpK7R
    • 这只是一个示例,您必须根据输入设置所有值。我修改了答案。
    • 是的,该州的值正在更新,但金额的文本字段未更新。我尝试设置 value 属性,但收到错误作为无效道具
    • 您需要将字符串转换为数字,反之亦然以计算并显示在文本字段中。可能 native-base 需要字符串,但您需要使用数字进行计算。对于错误消息,您应该显示完整的消息,因为它显示了原因
    • 计算没有问题。它正在更新文本字段(最后两个),如我现在添加的上图中所示。但是,输入字段值“投资金额”没有得到更新。我尝试将 value,defaultValue 设置为 {state.amount} 但没有更改数据。
    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多