首页 > 解决方案 > 在哪里放置 proptypes 验证?

问题描述

我的反应应用程序,我在重构阶段。我想将 redux 部分与组件分开。我对在哪里放置 proptypes 验证感到困惑?redux props 应该在容器文件中验证,组件 props 应该在组件上验证吗?还是应该在组件上处理这两种道具类型?还是装在容器里?这是我的代码。

import React, { Component } from 'react';
import { withRouter } from 'react-router-dom'; 

import PropTypes from 'prop-types';
import {bindActionCreators} from 'redux';
import { connect } from 'react-redux';
import { registerUser } from '../../../actions';

import { TextFieldGroup } from '../../../components/UI';

class RegisterScreen extends Component {
   state = {
      name: '',
      email: '',
      password: '',
      password2: '', 
      errors: {}
   };

   componentDidMount() {
      if (this.props.auth.isAuthenticated) {
         this.props.history.push('./dashboard');
      }
   }

   componentWillReceiveProps(nextProps) {
      if (nextProps.errors) {
         this.setState({ errors: nextProps.errors });
      }
   }

   onChange = e => {
      this.setState({
         [e.target.name]: e.target.value 
      });
   }

   onSubmit = e => {
      e.preventDefault();

      const newUser = {
         name: this.state.name,
         email: this.state.email,
         password: this.state.password,
         password2: this.state.password2
      }

      this.props.registerUser(newUser, this.props.history);
   } 

   render() {
      const { errors } = this.state;

      return (
         <div className='register'>
            <div className='container'>
               <div className='row'>
                  <div className='col-md-8 m-auto'>

                     <h1 className='display-4 text-center'>Sign Up</h1>

                     <p className='lead text-center'>
                        Create Your Developer Connector Account
                     </p>

                     <form noValidate onSubmit={this.onSubmit}>
                        <TextFieldGroup 
                           className={errors.email}
                           placeholder="* Full Name" 
                           name="name" 
                           value={this.state.name}
                           onChange={this.onChange}
                           error={errors.name}
                        />

                        <TextFieldGroup 
                           type='email'
                           className={errors.email}
                           placeholder="* Email Address" 
                           name="email" 
                           value={this.state.email}
                           onChange={this.onChange}
                           error={errors.email}
                           info='This site uses Gravatar so if you want a profile image, use a Gravatar email'
                        /> 

                        <TextFieldGroup 
                           type='password'
                           className={errors.password}
                           placeholder="* Password" 
                           name="password" 
                           value={this.state.password}
                           onChange={this.onChange} 
                           error={errors.password}
                        /> 

                        <TextFieldGroup 
                           type='password' 
                           className={errors.password2}
                           placeholder="* Confirm Password" 
                           name="password2" 
                           value={this.state.password2}
                           onChange={this.onChange}
                           error={errors.password2}
                        /> 

                        <input type='submit' className='btn btn-info btn-block mt-4' />
                     </form>

                  </div>
               </div>
            </div>
         </div>
      );
   }
}

RegisterScreen.propTypes = {
   registerUser: PropTypes.func.isRequired,
   auth: PropTypes.object.isRequired,
   errors: PropTypes.object.isRequired
} 

const mapStateToProps = state => ({
   auth: state.auth,
   errors: state.errors
});

const mapDispatchToProps = dispatch => ({
   registerUser: bindActionCreators(registerUser, dispatch)
});

export default connect(mapStateToProps, mapDispatchToProps)(withRouter(RegisterScreen));

标签: reactjsredux

解决方案


您应该像在示例中那样在组件中定义 PropTypes。在决定何时使用 PropTypes 进行静态类型化时,您应该始终防止传入的 props 在渲染时直接影响组件的预期结果。我的意思是,如果组件需要“auth”或“errors”道具,那么您应该为接收这些属性的组件定义 PropTypes,无论是通过 HoC(在这种情况下为 redux)还是任何其他向下传递数据的模式。


推荐阅读