【问题标题】:Multiple switches (toggels) enable all at once when generated from array react-native从数组 react-native 生成​​时,多个开关(切换)同时启用
【发布时间】:2018-09-13 18:30:55
【问题描述】:

现在我的构造函数中有一个这样的数组:

    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>
 )

这是错误:

【问题讨论】:

    标签: javascript arrays reactjs react-native


    【解决方案1】:

    我认为您必须跟踪元素索引并为 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

    【讨论】:

    • 我只是把你的答案和我的混合在一起,它可以工作,谢谢:-)
    【解决方案2】:

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

    【讨论】:

    • 长度未知。我知道状态问题我只是不知道如何解决它或做其他事情:-)
    【解决方案3】:

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

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

    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>
     )
    

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

    【讨论】:

    • 我在尝试使用您的示例时收到此错误:undefined is not an object (evalating '_this2.state.toggled[item.id] 你知道为什么吗?
    • 您能否用代码的当前状态更新您的问题。不要删除您以前的版本。只需在下面添加。也请添加您的承包商代码。
    • @MaikenMadsen 就像我在回答中告诉你的那样,你需要在构造函数中初始化切换值。
    【解决方案4】:

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

    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'
      }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-22
      • 2021-08-05
      • 2017-10-30
      • 2016-05-27
      • 1970-01-01
      • 1970-01-01
      • 2021-07-05
      • 1970-01-01
      相关资源
      最近更新 更多