调度操作创建器语法react-redux

dispatching action creator syntax react-redux

本文关键字:语法 react-redux 创建 操作 调度      更新时间:2023-09-26

我对youtube上的教程感到困惑。我将两个函数作为对象传递给mapDispatchtoProps和下面的函数,

import axios from 'axios'
export default (userdata) => {
    return dispatch => {
        return axios.post('/api/users', userdata);
    }
}

这是第二个函数或操作创建器

import {ADD_FLASH_MESSAGE} from './types'
    export function addFlashMessage(message)
    {
        return{
            type:ADD_FLASH_MESSAGE,
            message
        }
    }

现在我把它们都传递到这个文件中,

import React from 'react'
import SignupForm from '../signup/SignupForm'
import {connect} from 'react-redux'
import signupRequest from './signupRequest'
import {addFlashMessage} from '../../actions/addFlashMessage'
class Signup extends React.Component {
    render() {
        const {signupRequest,addFlashMessage} = this.props;
        return (
            <div className="row">
            <div className="col-md-4 col-md-offset-4">
            <SignupForm signupRequest={signupRequest} addFlashMessage={addFlashMessage}/>
            </div>
            </div>
            )
    }
}
Signup.propTypes = {
    signupRequest: React.PropTypes.func.isRequired,
    addFlashMessage:React.PropTypes.func.isRequired
}
export default connect(null, {signupRequest,addFlashMessage})(Signup)

和在表示组件中我使用它们

import React from 'react'
import classname from 'classnames'
import {browserHistory} from 'react-router'
import validateInput from '../../../server/shared/validateInput'
import TextFieldGroup from  '../fieldgroup/textFieldGroup'
export default class SignupForm extends React.Component {
    constructor(props){
        super(props);
        this.state ={
            username: "",
            password: "",
            passwordConfirmation: "",
            email: "",
            errors:{},
            isLoading:false
        }
    }
    onChange(e){
        this.setState(
        {
            [e.target.name] : e.target.value
        })
    }
    isValid(){
        const {errors,isValid} =validateInput(this.state)
        if(!isValid){
            this.setState({errors});
        }
        return isValid;
    }
    onSubmit(e){
        e.preventDefault();
        if(this.isValid()){
            this.setState({
                errors:{},
                isLoading:true
            });
            this.props.signupRequest(this.state).then(
                () => {
                    this.props.addFlashMessage({
                        type:'success',
                        text:'Sign up successfull, Welcome aboard!'
                    });
                    browserHistory.push('/');
                }, ({data}) => this.setState({errors:data,isLoading:false}));
        }
    }
    render(){
        const {errors} = this.state;
        return (
            <form onSubmit={this.onSubmit.bind(this)}>
            <h1>Sign Up For Free</h1>   
            <TextFieldGroup
            error={errors.username} 
            label="Username"
            value={this.state.username}
            onChange={this.onChange.bind(this)}
            field="username"
            />
            <TextFieldGroup
            error={errors.email} label="Email"
            value={this.state.email} onChange={this.onChange.bind(this)}
            field="email" 
            />
            <TextFieldGroup
            error={errors.password} label="Password"
            value={this.state.password} onChange={this.onChange.bind(this)}
            field="password" type="password"/>
            <TextFieldGroup
            error={errors.passwordConfirmation} label="Password Confirmation"
            value={this.state.passwordConfirmation} onChange={this.onChange.bind(this)}
            field="passwordConfirmation" type="password" />
            <div className="form-group">
            <button disabled={this.state.isLoading} className="btn btn-primary btn-lg">
            Sign Up
            </button>
            </div>
            </form>
            )
    }
}
SignupForm.propTypes = {
    signupRequest: React.PropTypes.func.isRequired,
    addFlashMessage: React.PropTypes.func.isRequired
}

我不明白它是如何在提交函数中工作的,我在react中还是新手,尤其是redux,从我学到的东西中,为了使通知或更新状态在存储中,我们必须调度和操作,所以在我的脑海中,我想是这样的,

调度(this.props.addFlashMessage({action}),然后reducer完成它的工作。

但是this.props.addflashmessage怎么可以被分派,而this.props.signuprequest(this.state)只返回一个以分派为参数的函数并返回api调用结果呢?

this.props.signupRequest(this.state).then(
                () => {
                    this.props.addFlashMessage({
                        type:'success',
                        text:'Sign up successfull, Welcome aboard!'
                    });
                    browserHistory.push('/');
                }, ({data}) => this.setState({errors:data,isLoading:false}));

原因很简单:

import {connect} from 'react-redux'

这一行所做的,是用dispatch包裹你传递的所有动作,并自动调度它们。查看官方文档以获得更深入的理解:http://redux.js.org/docs/basics/UsageWithReact.html

在本例中,您执行了

export default connect(null, {signupRequest,addFlashMessage})(Signup)

注册。

Stabley说的完全正确。我只是想补充一些细节。基本上,连接是一个HOC,它可以为您的组件添加更多功能。

这个神奇的函数是bindActionCreators,它会把一个值是action creator的对象,变成一个具有相同键的对象,但是每个action creator都被包装成一个调度调用,所以它们可以被直接调用。你可以在这里查看更详细的文档。

wrapActionCreators.js

import { bindActionCreators } from 'redux'
export default function wrapActionCreators(actionCreators) {
return dispatch => bindActionCreators(actionCreators, dispatch)
}

connect.js

mapDispatch = wrapActionCreators(mapDispatchToProps)
const mappedDispatch = mapDispatch(store.dispatch, props)

所以在connect函数中它调用了bindActionCreators和你传递给它的动作