React Native:在循环显示的文本输入数组中,如何获取第n个元素并分别修改这些元素?

问题描述 投票:1回答:1

在这个模块中,我试图创建一个类似于twitter中的调查模块。

首先,文本输入边框的颜色是灰色的,当我对焦(单击)文本输入时,只有其中一个(单击一个)必须为蓝色。当我输入文本时,它们都不应该得到相同的值。我应该能够通过单击加号图标获取我创建的每个文本输入值,作为字符串

我应该使用平面列表还是列表视图而不是for循环? React-Native Listview, press row and change that row style我也试图根据这个例子来解决它。我稍微改变了这个例子,我能够改变点击的边框颜色。但是,我仍然无法获得价值......

任何解决方案的建议?谢谢。

screenshot 1

screenshot 2

这是我的代码;

changeInputBorderColor = () => {
    const newinputBorderColor = cloneDeep(this.state.inputBorderColor);
    newinputBorderColor.bar = '#04A5F5';
    this.setState({inputBorderColor: {bar: newinputBorderColor.bar}});
};
changeInputBorderColor2 = () => {
    this.setState({
        inputBorderColor: {
            bar: 'grey'
        }
    })
};
incrementInputCount = () => {
    if (this.state.inputCounter < 5) {
        this.setState(prevState => {
            return {inputCounter: prevState.inputCounter + 1}
        });
        console.log(this.state.inputCounter);
    }
    else {
        this.setState(prevState => {
            return {inputCounter: prevState.inputCounter}
        });
        alert("Maximum soru sayısına ulaştınız");
    }
};

render() {
    let surveyOptions = [];
    for (let i = 0; i < this.state.inputCounter; i++) {
        console.log(this.state.inputCounter);
        surveyOptions.push(
            <View key={i}>
                <View>
                    <TextInput
                        style={[styles._surveyTextInput, {borderColor: this.state.inputBorderColor.bar}]}
                        onChangeText={(text) => this.setState({text})}
                        value={this.state.text}
                        onFocus={this.changeInputBorderColor}
                        onBlur={this.changeInputBorderColor2}
                        placeholder={"Secenek " + (i + 1)}
                    />
                </View>
            </View>
        )
    }
    return (
        <View style={styles._surveyMainContainer}>
            <View style={{flex: 0.8}}>
                {surveyOptions}
                <TouchableOpacity style={{position: 'absolute', right: 5, top: 5}}>
                    <Ionicons name={"ios-close-circle"}
                              size={30}
                              color={'black'}
                    />
                </TouchableOpacity>
                <TouchableOpacity style={{position: 'absolute', right: 5, top: 45}}
                                  onPress={this.incrementInputCount}>
                    <Ionicons name={"ios-add-circle"}
                              size={30}
                              color={'blue'}
                    />
                </TouchableOpacity>
            </View>
            <View style={{flex: 0.2}}>
                <View
                    style={styles.renderSeparator}
                />
                <Text style={{fontWeight: 'bold', margin: 5}}>Anket süresi</Text>
            </View>
        </View>
    );
}
javascript android ios react-native twitter
1个回答
0
投票

您可以使用.map来完成它,但是您必须正确设置它,以便每个TextInput都有自己的状态值。目前你正在做的是为每个TextInput设置相同的状态值,这导致每个TextInput具有相同的值。显然不是你想要的。

  1. 在状态(textArray)中创建一个初始数组,其中所有值都为空字符串,这将用于存储每个TextInput的值。
  2. focusedIndex设置为null状态
  3. 创建一个使用先前状态值来更新当前状态的函数。
  4. 创建一个函数来处理盒子颜色的变化,它只会将TextInput指数与当前的focusedIndex进行比较
  5. 迭代textArray并创建TextInput组件。确保每个TextInput都有自己的状态值。
  6. 确保我们在onFocus中的onBlurTextInput中设置focusedIndex的值。当它模糊时,我们应该将值设置为null,以便在键盘解除时删除边框颜色。

所以我们可以做类似以下的事情

export default class App extends React.Component {

  constructor(props) {
    super(props);
    // construct an array with the number of textInputs we require, 
    // each value an empty string
    // set this array in state
    // set the focusedIndex to null
    let textArray = Array(6).fill('');
    this.state = {
      textArray: textArray,
      focusedIndex: null
    }
  }

  // this function will handle setting of the state when each TextInput changes
  onChangeText = (text, index) => {
    // as there are going to be a lot of setState calls
    // we need access the prevState before we set the next state.
    this.setState(prevState => {
      prevState.textArray[index] = text
      return {
        textArray: prevState.textArray
      }
    }, () => console.log(this.state.textArray))
  }

  // handle the border color
  handleBorderColor = (index) => {
    return index === this.state.focusedIndex ? 'red' : 'grey'
  }

  render() {
    // here we map the items in the `this.state.textArray` 
    // notice that each TextInput is give a specific value in state
    // that will stop the overlap
    return (
      <View style={styles.container}>
        {this.state.textArray.map((text, index) => {
          return <TextInput
            style={{height: 40, marginVertical: 10, borderColor: this.handleBorderColor(index), borderWidth: 1}}
            onChangeText={text => this.onChangeText(text, index)} 
            value={this.state.textArray[index]}
            placeholder={`placeholder for ${index}`}
            onFocus={() => this.setState({focusedIndex: index})}
            onBlur={() => this.setState({focusedIndex: null})}
          />
        })}
      </View>
    );
  }
}

如果您想要访问TextInput的特定值,您可以这样做

let value = this.state.textArray[index]; // where the index is the value you want

这是一个示例小吃,显示代码工作https://snack.expo.io/@andypandy/map-multiple-textinputs

看看以下关于状态的文章绝对值得,因为我在这个例子中使用了这些属性。

https://medium.learnreact.com/setstate-is-asynchronous-52ead919a3f0 https://medium.learnreact.com/setstate-takes-a-callback-1f71ad5d2296 https://medium.learnreact.com/setstate-takes-a-function-56eb940f84b6

© www.soinside.com 2019 - 2024. All rights reserved.