简体   繁体   中英

React Native - Redux - Passing Value from child to function in Parent

I'm having a bit of difficulty passing values from a Page component to a Container component. I'm also using Tcomb-form-native for the forms.

Basically, when I click the button, I want to pass the values from my form in AuthenticatePage to the AuthenticateContainer component to use for logging in. I'm not sure if this is the best way to do it, but any help would be greatly appreciated!

Here's my code so far:

AuthenticatePage.js

 'use strict' import React, { Component, PropTypes } from 'react'; import {Text, View, TouchableHighlight, AlertIOS} from 'react-native'; import t from 'tcomb-form-native' import _ from 'lodash' import EStyleSheet from 'react-native-extended-stylesheet' import ViewContainer from '../ViewContainer' var Form = t.form.Form; var User = t.struct({email: t.String, password: t.String}); const options = { auto: 'placeholders', fields: { email: { autoCapitalize: 'none', autoCorrect: false }, password: { autoCapitalize: 'none', autoCorrect: false, password: true, secureTextEntry: true } } }; export default class AuthenticatePage extends Component { static propTypes = { doLogin: PropTypes.func.isRequired, email: PropTypes.string, password: PropTypes.string, error: PropTypes.string.isRequired }; constructor(props) { super(props); } submitLogin (e) { e.preventDefault(); var value = this.refs.form.getValue(); console.log(value); return(() => this.props.doLogin(value)); } render() { return ( <ViewContainer> <Text> Welcome to Poqet! </Text> <View> <Form ref="form" type={User} options={options}/> </View> <View> <TouchableHighlight onPress={this.submitLogin.bind(this)} underlayColor='#99d9f4'> <Text>{_.capitalize('Login')}</Text> </TouchableHighlight> </View> </ViewContainer> ) } } 

AuthenticateContainer.js

 'use strict' import React, { Component, PropTypes } from 'react'; import AuthenticatePage from '../../components/Authenticate/AuthenticatePage' import { connect } from 'react-redux'; import { bindActionCreators } from 'redux' import * as sessionActionCreators from '../../redux/session'; import {Actions, ActionConst} from 'react-native-router-flux' class AuthenticateContainer extends Component { constructor(props) { super(props); this.state = { value: { email: '', password: '' } }; } handleLogin() { console.log(value) this.props.doLogin(value.email, value.password) .then(console.log("Login Succecss")) } render() { return ( <AuthenticatePage doLogin = {this.handleLogin.bind(this)} error = {this.props.error}/> ); } } AuthenticateContainer.propTypes = { doLogin: PropTypes.func.isRequired, email: PropTypes.string, password: PropTypes.string, error: PropTypes.string.isRequired }; export default connect( (state) => ({isFetching: state.session.isFetching, error: state.session.error}), (dispatch) => bindActionCreators(sessionActionCreators, dispatch) )(AuthenticateContainer) 

Thank you!

Edited code per Matan Gubkin's response:

AuthenticateContainer.js

 'use strict' import React, { Component, PropTypes } from 'react'; import AuthenticatePage from '../../components/Authenticate/AuthenticatePage' import { connect } from 'react-redux'; import { bindActionCreators } from 'redux' import * as sessionActionCreators from '../../redux/session'; import {Actions, ActionConst} from 'react-native-router-flux' class AuthenticateContainer extends Component { constructor(props) { super(props); this.state = { value: { email: '', password: '' } }; } handleLogin(value) { console.log(value) this.props.doLogin(value.email, value.password) .then(() => Actions.tabbar()) } render() { return ( <AuthenticatePage doLogin = {this.handleLogin.bind(this)} error = {this.props.error}/> ); } } AuthenticateContainer.propTypes = { doLogin: PropTypes.func.isRequired, email: PropTypes.string, password: PropTypes.string, error: PropTypes.isRequired }; export default connect( (state) => ({isFetching: state.session.isFetching, error: state.session.error}), (dispatch) => bindActionCreators(sessionActionCreators, dispatch) )(AuthenticateContainer) 

AuthenticatePage.js

 'use strict' import React, { Component, PropTypes } from 'react'; import {Text, View, TouchableHighlight, AlertIOS} from 'react-native'; import t from 'tcomb-form-native' import _ from 'lodash' import EStyleSheet from 'react-native-extended-stylesheet' import ViewContainer from '../ViewContainer' var Form = t.form.Form; var User = t.struct({email: t.String, password: t.String}); const options = { auto: 'placeholders', fields: { email: { autoCapitalize: 'none', autoCorrect: false }, password: { autoCapitalize: 'none', autoCorrect: false, password: true, secureTextEntry: true } } }; export default class AuthenticatePage extends Component { static propTypes = { doLogin: PropTypes.func.isRequired, email: PropTypes.string, password: PropTypes.string, error: PropTypes.string.isRequired }; constructor(props) { super(props); this.state = { value: '' } } onChangeForm( value ) { this.setState({ value: value }); } submitLogin (e) { e.preventDefault(); var value = this.refs.form.getValue(); console.log(value); return(this.props.doLogin(value)); } render() { return ( <ViewContainer> <Text> Welcome to Poqet! </Text> <View> <Form ref="form" type={User} options={options} onChange={this.onChangeForm.bind(this)}/> </View> <View> <TouchableHighlight onPress={this.props.doLogin(this.state.value)} underlayColor='#99d9f4'> <Text>{_.capitalize('Login')}</Text> </TouchableHighlight> </View> </ViewContainer> ) } } 

It's a really bad practice to use refs for such a simple task, personally i prefer to avoid refs if possible, as they are really not maintainable and much more complicated. tcomb-form-native components has an onChange event.

If i were you I would do it this way:

constructor(props) {
    super(props);

    this.state = { value: '' }
}


onChangeForm( value ) {

    this.setState({value: value);

}

render() {

    <View> 
     ...  
        <Form .. ... onChange={ this.onChangeForm.bind(this) } />
        <SomebuttonComponent onPress={  this.props.doLogin( this.state.value ) } />  
    </View>
}

and in the next component, simply call this.props.value to access value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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