当从阵列反应本机生成时,多个开关(toggels)一次启用

时间:2018-04-04 09:01:30

标签: javascript arrays reactjs react-native

现在我在构造函数中得到了一个这样的数组:

    words: ['test', 'test', 'test'],

在渲染中我想为每个元素生成一个带文本和切换(切换)的元素,如下所示:

const wordList = this.state.words.map((item, i) =>
    <View style={styles.wordsContainer}>
      <Text style={styles.pilgrimsWordText} key={i}>{item}</Text>
      <Switch
        style={styles.pilgrimsWordSwitch}
        onValueChange={(value) => {this.setState({ toggled: value })}}
        value={ this.state.toggled }
      />
    </View>
 )
之后,我只是在回归中显示元素。

生成元素并且一切看起来都很好但是当用户按下其中一个(切换)时,所有这些都会像图片一样启用:

picture of the elements (with text and switches)

如果只启用用户希望启用的一个开关(切换),您会怎么做?

__________编辑:___________ 这是我的构造函数:

 constructor(props) {
   super(props);
   this.state = {
     words: [{ id: 1, text: 'test'}, { id: 2, text: 'test'}, {id: 3, text: 'test'}],
     textInputValue: '',
   }
  }

现在地图看起来像这样:

const wordList = this.state.words.map((item, i) =>
    <View style={styles.wordsContainer}>
      <Text style={styles.pilgrimsWordText} key={item.id}>{item.text}</Text>
      <Switch
        style={styles.pilgrimsWordSwitch}
        onValueChange={(value) => {this.setState({ toggled: { [item.id]: value }})}}
        value={ this.state.toggled[item.id] }
      />
    </View>
 )

这是错误:

image of error

4 个答案:

答案 0 :(得分:0)

这是因为每个映射的组件使用相同的状态变量来确定它是否处于“切换”状态。您需要使用3个不同的状态变量,但如果列表的长度未知,则变得更加困难。

答案 1 :(得分:0)

您需要在数据/数组中使用唯一标识符来实现欲望行为。

如果您对数据进行如下更改,则可以为每个映射组件设置唯一的状态值。

words: [{ id: 1, text: 'test'}, { id: 2, text: 'test'}, {id: 3, text: 'test'}],
const wordList = this.state.words.map((item, i) =>
    <View style={styles.wordsContainer}>
      <Text style={styles.pilgrimsWordText} key={item.id}>{item.text}</Text>
      <Switch
        style={styles.pilgrimsWordSwitch}
        onValueChange={(value) => {this.setState({ toggled: { [item.id]: value })}}
        value={ this.state.toggled[item.id] }
      />
    </View>
 )

在构造函数中将初始切换状态值设置为空对象,如{}

答案 2 :(得分:0)

我认为您必须跟踪元素索引并重新构建words的数据,如我的示例所示:

class Example extends React.Component {
    constructor(props){
    super(props);
    this.state = {
      words: [
        {text: 'test', toggled: false},
        {text: 'test', toggled: false},
        {text: 'test', toggled: false}
      ]
    }
  }

  toggle(index, e){
    const words = [...this.state.words];
    words[index].toggled = !words[index].toggled;

    this.setState({ words });
  }

  render() {
    return (
        <div>
        {this.state.words.map((word, i) =>
            <span key={i}>
              {word.text}
              <input type="checkbox" onChange={this.toggle.bind(this, i)} />
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                   //bind a function with element index you just clicked
            </span>
        )}
        <br/><br/>
        {JSON.stringify(this.state.words)}
      </div>
    )
  }
}

Worked example

答案 3 :(得分:0)

Array.map为数组中的每个元素调用一次提供的回调函数,使用三个参数调用回调:元素的值 {},元素的索引,并且遍历数组对象

import React, { Component} from 'react';
import {
  Dimensions,
  StyleSheet,
  Switch,
  Text,
  View,
} from 'react-native';

const { height, width } = Dimensions.get('window');

export default class WordList extends Component {

  constructor(props: Object) {
    super(props);
    this.state = {
      words: [
        { id: 1, text: 'Notification', toggle:false}, 
        { id: 2, text: 'Wifi', toggle:false}, 
        { id: 3, text: 'Bluetooth', toggle:false}
      ]
    }
  };

 renderWordList(){
    const wordList = this.state.words.map((word, i, wordArray) =>
      <View key={word.id} style={styles.wordsContainer}>
        <Text>{word.text}</Text>
        <Switch
          style={styles.pilgrimsWordSwitch}
          onValueChange={(toggleValue) => {
            wordArray[i].toggle = toggleValue;
            this.setState({words: wordArray});
          }}
          value={ word.toggle }
        />
      </View>
    )
    return wordList;
  }

  render() {
    return (
      <View style={{flex: 1, justifyContent:'center', backgroundColor: 'gray'}}>
        {this.renderWordList()}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  wordsContainer: {
    alignItems:'center', 
    backgroundColor:'green',  
    flexDirection:'row',
    height:100, 
    ustifyContent:'center', 
    padding:20,
  },
  pilgrimsWordSwitch: {
    flex:1, 
    justifyContent:'flex-end'
  }
});

Render View of above Code