首页 > 解决方案 > React-Native Picker 问题 - 处理开关项目

问题描述

我对 Picker 选择器组件有疑问。所以你看到有一个带有字符串的 curriences 数组。我使用 Picker 在它们之间进行选择,并且我具有包含onValueChange在 Picker 中的道具的功能,然后出现了从选取器中选择项目的问题。

首先,我可以从选择器中选择任何项目,但是当我想再次选择时,我在列表中只有这个选择的项目: 然后我选择了多个项目 ,例如 EUR。当我想再次选择一个项目时,我只有这个: 在此处输入图像描述

此外,当我更改第一个选择器项目时 - 它也在第二个选择器中更改......不知道为什么。

还在这里添加整个代码:

import React, {Component} from 'react';
import {View, Text, TextInput, Picker} from 'react-native';
class CurrencyCashScreen extends React.Component {
  state = {
    currencies: ['USD', 'AUD', 'SGD', 'PHP', 'EUR'],
    base: 'PLN',
    amount: '',
    convertTo: 'EUR',
    result: '',
    date: '',
  };

  handleSelect = (itemValue, itemIndex) => {
    this.setState(
      {
        ...this.state,
        currencies: [itemValue],
        result: null,
      },
      this.calculate,
    );
  };

  handleInput = text => {
    this.setState(
      {
        ...this.state,
        amount: text,
        result: null,
        date: null,
      },
      this.calculate,
    );
  };

  calculate = () => {
    const amount = this.state.amount;
    if (amount === isNaN) {
      return;
    } else {
      fetch(`https://api.exchangeratesapi.io/latest?base=${this.state.base}`)
        .then(res => res.json())
        .then(data => {
          const date = data.date;
          const result = (data.rates[this.state.convertTo] * amount).toFixed(4);
          this.setState({
            ...this.state,
            result,
            date,
          });
        });
    }
  };

  handleSwap = e => {
    const base = this.state.base;
    const convertTo = this.state.convertTo;
    e.preventDefault();
    this.setState(
      {
        ...this.state,
        convertTo: base,
        base: convertTo,
        result: null,
      },
      this.calculate,
    );
  };
  render() {
    const {currencies, base, amount, convertTo, result} = this.state;
    return (
      <View>
        <Text>
          {amount} {base} is equevalent to
        </Text>
        <Text>
          {amount === '' ? '0' : result === null ? 'Calculating...' : result}{' '}
          {convertTo}
        </Text>
        <View>
          <View>
            <View>
              <TextInput
                keyboardType="numeric"
                value={amount}
                onChangeText={this.handleInput}
              />
              <Picker
                selectedValue={base}
                value={base}
                onValueChange={this.handleSelect}>
                {currencies.map((currency, index) => (
                  <Picker.Item label={currency} value={currency}>
                    {currency}
                  </Picker.Item>
                ))}
              </Picker>
            </View>
            <View>
              <TextInput
                editable={false}
                value={
                  amount === ''
                    ? '0'
                    : result === null
                    ? 'Calculating...'
                    : result
                }
              />
              <Picker
                selectedValue={convertTo}
                value={convertTo}
                onValueChange={this.handleSelect}>
                {currencies.map(currency => (
                  <Picker.Item label={currency} value={currency}>
                    {currency}
                  </Picker.Item>
                ))}
              </Picker>
            </View>
          </View>
          <View>
            <Text onClick={this.handleSwap}>CLICK ME</Text>
          </View>
        </View>
      </View>
    );
  }
}

export default CurrencyCashScreen;

请帮忙。

标签: javascriptreact-nativestatepicker

解决方案


在您的handleSelect函数中,您将currencies使用仅包含所选货币的列表覆盖存储状态。你应该停止这样做。

为什么不在selectedCurrencystate 中设置一个值并使用它来用当前值填充选择器,并在调用时更新它handleSelect

更新以添加更多帮助

当你初始化你的状态时,你设置货币如下:

state = {
    currencies: ['USD', 'AUD', 'SGD', 'PHP', 'EUR'],

当您的handleSelect函数被调用时,它会更改此列表的状态:

handleSelect = (itemValue, itemIndex) => {
    this.setState(
      {
        ...this.state,
        currencies: [itemValue], // <-- HERE! You're changing the list of currencies
        result: null,
      },
      this.calculate,
    );
  };

调用此方法后,您的货币列表就是您在选择器中选择的货币列表。

这就是为什么当您的组件重新渲染时,所有其他选项都会消失:

您使货币脱离状态,现在它只是一个包含您选择的数组:

const {currencies, base, amount, convertTo, result} = this.state;

因此,当您调用currencies.map创建Picker.Item组件时,在您的选择器中,您只有一种货币。

下一个大问题是你handleSelect从每个选择器调用相同的函数......所以你实际上不能选择两种不同的货币。

修复:

首先,我们需要两个选择器的两个句柄函数:

handleSelectBase = base => this.setState({ base }, this.calculate)
handleSelectConvertTo = convertTo => this.setState({ convertTo }, this.calculate)

然后更新您的两个选择器以使用正确的处理程序函数,您应该处于更好的位置。


推荐阅读