[英]React Native - Redux - Passing Value from child to function in Parent
我在將值從Page組件傳遞到Container組件時遇到了一些困難。 我還在表格中使用Tcomb-form-native。
基本上,當我單擊按鈕時,我要將值從AuthenticatePage中的表單傳遞到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); } 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)
謝謝!
根據Matan Gubkin的回復編輯的代碼:
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> ) } }
對於這樣一個簡單的任務,使用引用是一種非常糟糕的做法,我個人更喜歡盡可能避免引用,因為它們確實不可維護並且更加復雜。 tcomb-form-native組件具有onChange事件。
如果我是你,我會這樣做:
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>
}
在下一個組件中,只需調用this.props.value
即可訪問value。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.