【问题标题】:React Native - Conditionally render viewsReact Native - 有条件地渲染视图
【发布时间】:2017-04-12 21:50:01
【问题描述】:

我正在开发一个 React Native 应用程序。现在我希望它有两个视图。登录页面和主页。到目前为止看起来像这样:

index.ios.js

import React, { Component } from 'react';
import {
  AppRegistry,
  Dimensions,
  StyleSheet,
  Text,
  TextInput,
  Button,
  TouchableHighlight,
  View
} from 'react-native';
import Scanner from './app/components/Scanner';
import Login from './app/components/Login';
import Store from './app/mobx/store';

export default class TestApp extends Component {
  render() {
    if (Store.loggedIn()){
      return <Scanner />
    } else {
      return <Login store={Store} />
    }
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
    backgroundColor: '#114DA0'
  }
});

AppRegistry.registerComponent('TestApp', () => TestApp);

app/components/Login.js

import React, { Component } from 'react';

import {
  StyleSheet,
  Text,
  View,
  TextInput,
  ScrollView
} from 'react-native';
import Container from './Container';
import Button from './Button';
import Label from './Label';
import {observer} from 'mobx-react/native';

@observer
export default class Login extends Component {
  constructor() {
    super();
    this.state = {
      email: '',
      password: '',
      isLoggingIn: false,
      message: ''
    }
    this._userLogin = this._userLogin.bind(this);
  }
  _userLogin() {
    console.log("loggin in...")
    this.setState({isLoggingIn: true, message:''});
    var params = {
        email: this.state.email,
        password: this.state.password
    };
    var formBody = [];
    for (var property in params) {
      var encodedKey = encodeURIComponent(property);
      var encodedValue = encodeURIComponent(params[property]);
      formBody.push(encodedKey + "=" + encodedValue);
    }
    formBody = formBody.join("&");
    fetch("http://example.com:8000/auth/mobile_login", {
        method: "POST",
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: formBody
      })
      .then((response) => {
        return response.json()
      })
      .then((response) => {
        if (response.error) {
          this.setState({message: response.message});
        } else if (response.user) {
          this.props.store.logIn(response.user);
        }
      })
      .then(() => {
        this.setState({isLoggingIn: false})
      })
      .done();
  }
  render() {
    return (
        <ScrollView style={styles.scroll}>
          <Container>
            <Label text="Email" />
            <TextInput
              style={styles.textInput}
              onChangeText={(email) => this.setState({email})}
            />
          </Container>
          <Container>
            <Label text="Password" />
            <TextInput
              secureTextEntry={true}
              style={styles.textInput}
              onChangeText={(password) => this.setState({password})}
            />
          </Container>
          <Container>
            {!!this.state.message && (
              <Text style={{fontSize: 14, color: 'red', padding: 5}}>
                {this.state.message}
              </Text>
            )}
            <Button
              label="Sign In"
              styles={{button: styles.primaryButton, label: styles.buttonWhiteText}}
              onPress={this._userLogin} />
          </Container>
        </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  ...
});

app/components/Scanner.js

import React, { Component } from 'react';
import {
  AppRegistry,
  Dimensions,
  StyleSheet,
  Text,
  TouchableHighlight,
  View
} from 'react-native';
import Camera from 'react-native-camera';

export default class Scanner extends Component {
  constructor(){
    super();
    this.onBarCodeRead = this.onBarCodeRead.bind(this);
  }
  onBarCodeRead(e) {
    this.setState({text: e.data});
  }
  render() {
    return (
      <View style={styles.container}>
          <Camera
            ref={(cam) => {
              this.camera = cam;
            }}
            onBarCodeRead={this.onBarCodeRead}
            style={styles.preview}
            aspect={Camera.constants.Aspect.fill}>
          </Camera>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  ...
});

AppRegistry.registerComponent('Scanner', () => Scanner);

两个页面都可以正常工作,我可以通过登录页面登录我的服务。但是一旦我登录后,如何获取根组件来呈现 Scanner 页面?

【问题讨论】:

    标签: react-native react-native-ios mobx


    【解决方案1】:

    这里的关键是每次调用 setState 时都会调用 render:

    执行将 nextState 浅合并到当前状态。这是 用于从事件处理程序和触发 UI 更新的主要方法 服务器请求回调。 https://facebook.github.io/react/docs/react-component.html#setstate

    因此,可以通过检查此已登录状态并有条件地渲染内容来实现基于状态更改(在本例中为用户登录)更新组件的内容。

    以下面的代码为例:

    import React, { Component } from 'react';
    import './App.css';
    
    
    const ContentA = () => (
        <div>
            <h1>Filled with content A</h1>
        </div>
    );
    
    const ContentB = () => (
        <div>
            <h1>Filled with content B</h1>
        </div>
    );
    
    
    class App extends Component {
    
        state = {
            loggedIn: false
        };
    
        logIn = () => {
            this.setState({
                loggedIn: !this.state.loggedIn
            })
        };
    
        render() {
    
        const content = this.state.loggedIn ? <ContentA/> : <ContentB/>;
        return (
            <div>
                {content}
                <button onClick={this.logIn}>Clicky</button>
            </div>
        );
      }
    }
    
    export default App;
    

    每次单击按钮时,都会调用 setState,并且组件会根据 this.state.loggedIn 的值重新渲染。

    希望这会有所帮助,祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-20
      • 2020-02-18
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-03
      相关资源
      最近更新 更多