简体   繁体   English

如何在 React Native 的 state 中存储一个值?

[英]How to store a value in a state in React Native?

I've created a small form with two options.我创建了一个带有两个选项的小表单。 Basically I want the user to choose one option and to pass that value in the state "preference" (and further to pass that value in firebase).基本上我希望用户选择一个选项并在 state“首选项”中传递该值(并进一步在 firebase 中传递该值)。 I'm not sure if my approach with the "If Condition" to choose between options is the correct way because I am a Javascript and React Native beginner.我不确定我使用“If Condition”在选项之间进行选择的方法是否正确,因为我是 Javascript 和 React Native 初学者。

How would you approach this in terms of code?您将如何在代码方面解决这个问题?

 export default class ChooseOption extends Component {

    state = {
        option1: false,
        option2: false,
        preference: ''
    }

    chooseFirst = () => {
        if (this.state.option1 == false) {
            this.setState({ option1: true})
            this.setState({ option2: false })
        }
    }

    chooseSecond = () => {
        if (this.state.option2 == false) {
            this.setState({option2: true})
            this.setState({option1: false})
        }
    }

    render() {

        return(

            <View style={styles.container}>

                <Text style={styles.greeting}>Select one option:</Text>

                <View style={styles.form}>

                    <TouchableOpacity 
                        onPress={this.chooseFirst}
                        style={{flexDirection:'row', alignItems: 'center'}}>
                        <Icon 
                            name={this.state.option1 ? 'md-radio-button-on' : 'md-radio-button-off'}
                            size={30} 
                            color= {this.state.option1 ? 'green' : 'gray'}
                        />
                        <Text 
                            style={this.state.option1 ? styles.textOn : styles.textOff}>First Option</Text>
                    </TouchableOpacity>

                    <TouchableOpacity 
                        onPress={this.chooseSecond}
                        style={{marginTop: 30, flexDirection:'row', alignItems: 'center'}}>
                        <Icon 
                            name={this.state.option2 ? 'md-radio-button-on' : 'md-radio-button-off'}
                            size={30} 
                            color= {this.state.option2 ? 'green' : 'gray'}
                            />
                        <Text 
                            style={this.state.option2 ? styles.textOn : styles.textOff}>Second Option</Text>
                    </TouchableOpacity>

                </View> 
        </View>
       );
    }
}

const styles = StyleSheet.create({
container: {
    flex: 1,
},
greeting: {
    marginHorizontal: 30,
    marginTop: 307,
    fontSize: 30,
    lineHeight: 40,
},
form: {
    marginTop: 39,
    marginBottom: 115,
    marginHorizontal: 30
},
textOff: {
    color: 'gray',
    fontSize: 28,
    textTransform: 'none',
    letterSpacing: 2,
    left: 10
},
textOn: {
    color: 'green',
    fontSize: 28,
    textTransform: 'none',
    letterSpacing: 2,
    left: 10
},
})

If you want to use booleans to keep track of selected option then I would go with one variable, because in case of radio buttons only one at a time can be selected so second boolean is redundant.如果您想使用布尔值来跟踪所选选项,那么我将 go 与一个变量,因为在单选按钮的情况下,一次只能选择一个,因此第二个 boolean 是多余的。 Here is one example of doing it:这是一个这样做的例子:

export default class ChooseOption extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isOption1Selected: true,
      preference: '',
    };
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.greeting}>Select one option:</Text>
        <View style={styles.form}>
          <TouchableOpacity
            onPress={() => this.setState({ isOption1Selected: true })}
            style={{ flexDirection: 'row', alignItems: 'center' }}>
            <View
              name={this.state.isOption1Selected ? 'md-radio-button-on' : 'md-radio-button-off'}
              size={30}
              color={this.state.isOption1Selected ? 'green' : 'gray'}
            />
            <Text
              style={this.state.isOption1Selected ? styles.textOn : styles.textOff}>First Option</Text>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => this.setState({ isOption1Selected: false })}
            style={{ marginTop: 30, flexDirection: 'row', alignItems: 'center' }}>
            <View
              name={!this.state.isOption1Selected ? 'md-radio-button-on' : 'md-radio-button-off'}
              size={30}
              color={!this.state.isOption1Selected ? 'green' : 'gray'}
            />
            <Text
              style={!this.state.isOption1Selected ? styles.textOn : styles.textOff}>Second Option</Text>
          </TouchableOpacity>
        </View>
      </View>
    );
  }
}

But imagine if you have to add more options then it would be better to keep track of an id of selected option which you could implement in this way:但是想象一下,如果您必须添加更多选项,那么最好跟踪您可以通过这种方式实现的所选选项的 id:

export default class ChooseOption extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedOptionId: 0,
      preference: '',
    };
  }

  render() {
    const { selectedOptionId } = this.state;
    return (
      <View style={styles.container}>
        <Text style={styles.greeting}>Select one option:</Text>
        <View style={styles.form}>
          <TouchableOpacity
            onPress={() => this.setState({ selectedOptionId: 0, preference: 'First option' })}
            style={{ flexDirection: 'row', alignItems: 'center' }}>
            <View
              name={selectedOptionId === 0 ? 'md-radio-button-on' : 'md-radio-button-off'}
              size={30}
              color={selectedOptionId === 0 ? 'green' : 'gray'}
            />
            <Text
              style={selectedOptionId === 0 ? styles.textOn : styles.textOff}>First Option</Text>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => this.setState({ selectedOptionId: 1, preference: 'Second option' })}
            style={{ marginTop: 30, flexDirection: 'row', alignItems: 'center' }}>
            <View
              name={selectedOptionId === 1 ? 'md-radio-button-on' : 'md-radio-button-off'}
              size={30}
              color={selectedOptionId === 1 ? 'green' : 'gray'}
            />
            <Text
              style={selectedOptionId === 1 ? styles.textOn : styles.textOff}>Second Option</Text>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => this.setState({ selectedOptionId: 2, preference: 'Third option' })}
            style={{ marginTop: 30, flexDirection: 'row', alignItems: 'center' }}>
            <View
              name={selectedOptionId === 2 ? 'md-radio-button-on' : 'md-radio-button-off'}
              size={30}
              color={selectedOptionId === 2 ? 'green' : 'gray'}
            />
            <Text
              style={selectedOptionId === 2 ? styles.textOn : styles.textOff}>Third Option</Text>
          </TouchableOpacity>
        </View>
      </View>
    );
  }
}

And finally you could write a function to generate all the options from predefined array so that your code stays clean:最后你可以编写一个 function 来从预定义的数组中生成所有选项,这样你的代码就会保持干净:

const options = [
  { id: 0, text: 'First option'},
  { id: 1, text: 'Second option'},
  { id: 2, text: 'Third option'},
]

export default class ChooseOption extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedOptionId: 0,
      preference: '',
    };
  }

  createOption(optionData) {
    const { selectedOptionId } = this.state;
    const { id, text } = optionData;
    return (
      <TouchableOpacity
        key={id}
        onPress={() => this.setState({ selectedOptionId: id, preference: text })}
        style={{ flexDirection: 'row', alignItems: 'center' }}>
        <View
          name={selectedOptionId === id ? 'md-radio-button-on' : 'md-radio-button-off'}
          size={30}
          color={selectedOptionId === id ? 'green' : 'gray'}
        />
        <Text
          style={selectedOptionId === id ? styles.textOn : styles.textOff}>{text}</Text>
      </TouchableOpacity>
    );
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.greeting}>Select one option:</Text>
        <View style={styles.form}>
          {
            options.map((op) => this.createOption(op))
          }
        </View>
      </View>
    );
  }
}

UPDATE更新

If you want to print preference in console when it is selected, you can do something similar to what you did first time by calling custom function in TouchableOpacity but in a bit different way: onPress={() => this.select(id, text)} .如果您想在选择时在控制台中打印首选项,您可以通过在 TouchableOpacity 中调用自定义 function 来执行与第一次类似的操作,但方式有所不同: onPress={() => this.select(id, text)} . And then define this function like:然后定义这个 function 像:

select(id, text) {
  this.setState({ selectedOptionId: id, preference: text });
  console.log(text);
}

Option for what?选择什么? Lets assume its for theme: option1 (dark) and option2 (light)让我们假设它的主题:option1(深色)和 option2(浅色)

Lets say its option for themes让我们说它的主题选项

  const THEMES = {
    DARK: "dark",
    LIGHT: "light"
  };

  state = {
    selectedTheme : undefined,
    preference: ''
  }

  chooseFirst = () => {     
    this.setState({ selectedTheme:THEMES.DARK })    
  }

  chooseSecond = () => {
    this.setState({ selectedTheme:THEMES.LIGHT  })
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM