在 React-Native Navigator 中传递道具/状态 [英] Passing props / state in React-Native Navigator

查看:66
本文介绍了在 React-Native Navigator 中传递道具/状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此处响应 Native 新手.

React Native newbie here.

我正在尝试构建一个简单的 React Native 应用程序以供练习,它本质上只是一个多页联系表单.

I'm trying to build a simple React Native app for practice that is essentially just a multi-page contact form.

当我通过导航器(navigatorRenderScene 函数)渲染它们时,我无法找出将道具/状态传递给我的子组件的最佳方式

I'm having trouble figuring out the best way to pass props / state to my child components when I'm rendering them via the navigator (navigatorRenderScene function)

每当我尝试在这里为我的组件分配 props 时,它允许我传递一个字符串而不是一个函数或一个对象.例如在组件 First 中,我试图传递一个字符串和一个函数.页面呈现后,只有字符串会保留其值.

Whenever I try to assign props to my component here, it allows me to pass a string but not a function or an object. For example in the component First, I'm trying to pass a string and a function. Only the string will hold its value once the page is rendered.

我这样做完全错误吗?我是否需要研究某种状态管理系统,如 Flux 或 Redux?甚至可能是 redux 路由器包?(说实话还没碰过这些)

Am I doing this completely the wrong way? Do I need to look into some kind of state management system like Flux or Redux? Maybe even the redux router package? (Haven't even touched these yet to be honest)

路由一切都很好,只是我无法弄清楚道具/状态.

The routing is all working great, it's just the props / state that I can't figure out.

这是我的索引

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

import { Container, Header, Title, Content, List, ListItem, InputGroup, Input, Button, Icon, Picker } from 'native-base'

// a bunch of crap here being imported that I don't need, I'll trim it down later.

import First from './components/First'
import Second from './components/Second'

class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      text : 'initial state',
      sentBy : '',
      company : '',
      phoneNumber : ''
    };
    this.testFunc = this.testFunc.bind(this)
  }
  // end constructor

  mostRecentPush() {
    // firebase stuff, not really important to the problem
    console.log('pushing input data to DB')
    firebase.database().ref('mostRecent/').set({
      'body' : this.state.text,
      'sentBy' : this.state.sentBy,
      'location' : this.state.pickerValue,
      'company' : this.state.company
    });

    firebase.database().ref('emails/').push({
      'body' : this.state.text,
      'sentBy' : this.state.sentBy,
      'location' : this.state.pickerValue,
      'company' : this.state.company
    })
  }
  // end mostRecentPush() / firebase stuff

  onButtonPress() {
    this.props.navigator.push({
      id: 'Second'
    })
  } // end onButtonPress

  testFunc() {
    console.log('calling this from the index')
  }

  render() {
    console.log('rendering home')
    return (
        <Navigator
          initialRoute = {{
            id: 'First'
          }}
          renderScene={
            this.navigatorRenderScene
          }
         />
      )
  } // end render

  navigatorRenderScene(route, navigator) {
    _navigator = navigator;  
    switch (route.id){
      case 'First':
        return(<First testString="cat123" testFunc={this.testFunc} navigator={navigator} title="First" />)
        // passing our navigator value as props so that the component has access to it
      case 'Second':
        return(<Second navigator={navigator} title="Second" />)
      case 'Third':
        return(<Third navigator={navigator} title="Third" />)
      case 'Fourth':
        return(<Fourth navigator={navigator} title="Fourth" />)
      case 'Fifth':
        return(<Fifth navigator={navigator} title="Fifth" />)
    } //end switch
  } // end navigatorRenderScene
} // end component

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

这是一个示例组件,首先

And here's an example component, First

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

import { Container, Header, Title, Content, List, ListItem, InputGroup, Input, Button, Icon, Picker } from 'native-base'

// too much stuff being imported, will clean this up later

class First extends Component {

  constructor(props) {
    super(props)
    this.onButtonPress = this.onButtonPress.bind(this)
  }

  onButtonPress() {
    this.setState({
      text: 'changed state from first component'
    })

    console.log(this.state)

    this.props.navigator.push({
      id: 'Second'
    })
  }

  render() {
    return(
        <Container>
         {console.log('rendering first')}
            <Content>
                <List>
                    <ListItem>
                        <InputGroup>
                            <Input 
                              placeholder='Name' 
                            />
                        </InputGroup>
                    </ListItem>
               </List>
                <TouchableHighlight onPress={this.onButtonPress}>
                  <Text>Go to Page 2</Text>
                </TouchableHighlight>
            </Content>
        </Container>
      )
  }
}


export default First

推荐答案

我认为问题在于范围.将 renderScene 属性设置为导航器时,您并没有将该函数绑定到实际的类,因此当 navigatorRenderScene 被执行时,它的作用域与 testFunc 不同.

I think the the problem it's with the scope. When setting the renderScene prop to the navigator, you are not binding that function to the actual class, therefore when the navigatorRenderScene gets executed, the scope it's not the same as testFunc.

尝试更改这行代码:

navigatorRenderScene(route, navigator) {
  //...
}

为此:

navigatorRenderScene = (route, navigator) => {
  // ...
}

箭头函数会将 navigatorRenderScene 绑定到类,因此 this.testFunc 将存在于那里.

The arrow function will bind the navigatorRenderScene to the class, therefore this.testFunc will exist there.

其他绑定选项

如果你不想使用箭头函数,你可以在 constructor 中尝试这样的东西.

If you don't want to use an arrow function, you could try something like this in the constructor.

// First options
this.navigatorRenderScene = this.navigatorRenderScene.bind(this)

或者也可以直接在回调上使用bind方法

Or you can also use the bind method directly on the callback

// Second option
renderScene={
  this.navigatorRenderScene.bind(this)
}

或者箭头函数

// Third option
renderScene={
  (route, navigator) => this.navigatorRenderScene(route, navigator)
}

让我知道这是否有效.祝你好运!

Let me know if this works. Good luck!

这篇关于在 React-Native Navigator 中传递道具/状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆