【问题标题】:React Native - Redux - Passing Value from child to function in ParentReact Native - Redux - 将值从子传递到父函数
【发布时间】:2016-08-29 18:42:42
【问题描述】:

我在将值从 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>
        )
    }
}

【问题讨论】:

    标签: javascript reactjs react-native redux


    【解决方案1】:

    在这样一个简单的任务中使用 refs 是一种非常糟糕的做法,我个人更喜欢尽可能避免使用 refs,因为它们确实不可维护而且要复杂得多。 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 即可访问值。

    【讨论】:

    • 嗨,Matan,这段代码应该在 AuthenticatePage.js 中,对吗?当我将代码编辑为此时,我得到一个 setState(): Cannot update during a state transition 错误。我已经编辑了上面的问题以反映新代码。
    • 尝试将您的“this.props.login”移动到另一种方法
    猜你喜欢
    • 1970-01-01
    • 2016-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多