Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React JS表单验证逻辑位于子级还是父级?_Javascript_Reactjs_React Native - Fatal编程技术网

Javascript React JS表单验证逻辑位于子级还是父级?

Javascript React JS表单验证逻辑位于子级还是父级?,javascript,reactjs,react-native,Javascript,Reactjs,React Native,我不确定我是否理解如何组织我的第一个React JS应用程序,比如简单的验证逻辑。我的想法是将尽可能多的逻辑放在每个子组件中,但在我看来,更符合逻辑的地方是父组件。但这对我来说似乎是错误的,因为家长最终可能会为所有孩子编写大量代码。我已经包括了一个真正简单的例子来说明这个问题 在我的示例代码中,有一个用于输入框的小的子组件,一个中间组件包含两个输入框(我们称之为用户名控件),然后顶部组件是一个编辑页面。每个组件都有自己版本的isValid。最低的子级验证输入在有效之前是否为空。中间组件验证两个输

我不确定我是否理解如何组织我的第一个React JS应用程序,比如简单的验证逻辑。我的想法是将尽可能多的逻辑放在每个子组件中,但在我看来,更符合逻辑的地方是父组件。但这对我来说似乎是错误的,因为家长最终可能会为所有孩子编写大量代码。我已经包括了一个真正简单的例子来说明这个问题

在我的示例代码中,有一个用于输入框的小的子组件,一个中间组件包含两个输入框(我们称之为用户名控件),然后顶部组件是一个编辑页面。每个组件都有自己版本的
isValid
。最低的子级验证输入在有效之前是否为空。中间组件验证两个输入框是否包含内容。顶部的父编辑页面与中间的组件执行相同的操作。我的问题是,存储这个简单验证逻辑的“理想”位置或级别是什么

提前考虑顶层编辑页面,该页面有一个简单的按钮,只有在选中所有验证时才应启用该按钮。这让我感到困惑的是,如果您使用各种规则管理表单上的许多部分。因此,不仅用户名部分需要有效,其他几个部分也需要有效

我的主要困惑是,我认为我遗漏了一些简单的东西,因为当涉及到顶部组件(编辑页面)上的按钮时,我认为中间组件(用户控件)无法传达其验证状态,除非我使用引用。在阅读了一些参考资料之后,它们似乎并没有被过度使用。如果编辑页面无法从验证的子用户名控件获得反馈,则父用户需要执行验证。对于大型表单,这意味着在父编辑页面中存储了大量验证逻辑。这可能是正常的,我只是不确定

有人能在我概述的场景中验证放置简单
的“正确”位置是否有效吗

class InputBox extends React.Component {
  constructor(props) {
    super(props);
    this.handleInputChange = this.handleInputChange.bind(this);
  }
  handleInputChange(e) {
    this.props.onChange(e);
  }
  render() {
    const inputValue = this.props.value;
    const inputName = this.props.name;
    const isValid = this.props.isValid;
    const label = this.props.label;
    const msg = isValid === true ? 'true' : 'false';
    return (
      <div>
        <span>{label}</span>
        <input type="text"
          name={inputName}
          value={inputValue}
          onChange={this.handleInputChange} />
        <span>Is this textbox valid = {msg}</span>
      </div>
    )}
}
class UserNameControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(e) {
    const controlName = e.target.name;
    const newValue = e.target.value;
    const inputValue1 = controlName === 'input1' ? newValue : this.props.value1;
    const inputValue2 = controlName === 'input2' ? newValue : this.props.value2;
    const isValid = inputValue1 === '' || inputValue2 === '' ? false : true;
    this.props.onChange(controlName,newValue,isValid);
  }
  render() {
    const inputValue1 = this.props.value1;
    const inputValue2 = this.props.value2;
    const isTextValid1 = inputValue1 === '' ? false : true;
    const isTextValid2 = inputValue2 === '' ? false : true;
    const msg1 = isTextValid1 === true ? 'true' : 'false';
    const msg2 = isTextValid2 === true ? 'true' : 'false';
    const isSectionValidMsg = inputValue1 === '' || inputValue2 === '' ? 'false' : 'true';
    const isValid = inputValue1 === '' || inputValue2 === '' ? false : true;
    //this.props.isValid(isValid);
    return (
      <div>
        <div><h2>User Name Control Header</h2></div>
        <InputBox
          label='First Name: '
          name='input1'
          value={inputValue1}
          isValid={isTextValid1}
          onChange={this.handleChange}/>
          <br/>
        <InputBox
          label='Last Name: '
          name='input2'
          value={inputValue2}
          isValid={isTextValid2}
          onChange={this.handleChange}/>
        <div>
           <h4>User Name Control Footer: Is section valid = {isSectionValidMsg}</h4>
        </div>
       </div>
    )}
}
class EditPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      pageIsValid: false,
      textValue1: '',
      textValue2: '',
      section1Valid: false
    };
    this.handleChange = this.handleChange.bind(this);
    this.updateSection1Status = this.updateSection1Status.bind(this);
  }
  updateSection1Status(boolValue) {
    this.setState({section1Valid: boolValue});
  }
  handleChange(controlName,inputValue,isSectionValid) {
    this.setState({section1Valid: isSectionValid});
    if(controlName==='input1') {
      this.setState({textValue1: inputValue});
    }
    if(controlName==='input2') {
      this.setState({textValue2: inputValue});
    }
  }

  render() {
    const isFormValid = this.state.textValue1 === '' || this.state.textValue2 === '' ? false : true;
    //const formValidMsg = isFormValid ? 'True' : 'False';
    const formValidMsg = this.state.section1Valid ? 'True' : 'False';
    return (
      <form>
      <h1>Edit Form</h1>
        <div>
          <UserNameControl
            value1={this.state.textValue1}
            value2={this.state.textValue2}
            onChange={this.handleChange}
            />
        </div>
        <div>
          <h4>Is form valid = {formValidMsg}</h4>
        </div>
      </form>
    );
  }
}

ReactDOM.render(
  <EditPage/>,
  document.getElementById('root')
);
类InputBox扩展了React.Component{
建造师(道具){
超级(道具);
this.handleInputChange=this.handleInputChange.bind(this);
}
handleInputChange(e){
此.props.onChange(e);
}
render(){
const inputValue=this.props.value;
const inputName=this.props.name;
const isValid=this.props.isValid;
常量标签=this.props.label;
const msg=isValid==true?'true':'false';
返回(
{label}
此文本框是否有效={msg}
)}
}
类UserNameControl扩展了React.Component{
建造师(道具){
超级(道具);
this.handleChange=this.handleChange.bind(this);
}
手变(e){
const controlName=e.target.name;
const newValue=e.target.value;
常量inputValue1=controlName=='input1'?新值:this.props.value1;
常量inputValue2=controlName=='input2'?新值:this.props.value2;
常量isValid=inputValue1==''| | inputValue2==''?false:true;
this.props.onChange(controlName,newValue,isValid);
}
render(){
const inputValue1=this.props.value1;
const inputValue2=this.props.value2;
const isTextValid1=inputValue1==''?false:true;
const isTextValid2=inputValue2==''?false:true;
常量msg1=isTextValid1==true?'true':'false';
常量msg2=isTextValid2==true?'true':'false';
const IsSectionValidMg=inputValue1==''| | inputValue2==''假':'真';
常量isValid=inputValue1==''| | inputValue2==''?false:true;
//this.props.isValid(isValid);
返回(
用户名控制头

用户名控件页脚:节是否有效={IsSectionValidMg} )} } 类EditPage扩展了React.Component{ 建造师(道具){ 超级(道具); 此.state={ pageIsValid:false, textValue1:“”, textValue2:“”, 第1节有效:错误 }; this.handleChange=this.handleChange.bind(this); this.updateSection1Status=this.updateSection1Status.bind(this); } updateSection1Status(布尔值){ this.setState({section1Valid:boolValue}); } handleChange(controlName、inputValue、isSectionValid){ this.setState({section1Valid:isSectionValid}); 如果(controlName==='input1'){ this.setState({textValue1:inputValue}); } 如果(controlName==='input2'){ this.setState({textValue2:inputValue}); } } render(){ const isFormValid=this.state.textValue1==''this.state.textValue2==''?false:true; //const formvalidsg=isFormValid?'True':'False'; const formvalidsg=this.state.section1Valid?'True':'False'; 返回( 编辑表格 form valid={FormValidMg} ); } } ReactDOM.render( , document.getElementById('root')) );
我认为您走的是正确的道路,父级应该处理大部分验证,因为这使子输入变得更通用,因此在整个应用程序中更可重用。在这个特定场景中,我认为子组件应该尽可能通用,中间组件应该处理大部分验证逻辑,并将结果传递给父组件。然而,在这种情况下,您可能还需要在父级进行验证,但老实说,整个过程可能只重构为两个组件,而不是三个。以下是我将如何处理您的场景:

import React from 'react'

const notEmptyValidation = value => Boolean(value)


const InputBox = props => {
    const {validation, label, name} = props;

    const [localValue, setValue] = React.useState(props.value||"");

    const onChange = e => {
       setValue(e.target.value);
       if(typeof props.onChange === "function"){
         return props.onChange(e) 
      }
     }

    const isValid = () => {
      if(typeof validation === "function"){
         return validation(localValue) 
      }
      return true
    }

    React.useEffect(() => {
      //this allows the component to be used as either a controlled or uncontrolled input
      setValue(props.value||"")
    }, [props.value])

    return (
      <div>
        <span>{label}</span>
        <input type="text"
          name={name}
          value={localValue}
          onChange={onChange} />
        <span>Is this textbox valid = {`${isValid() ? "true":"false"}`}</span>
      </div>
    )
}

const UserNameControl = props => {

  const [input, setInput] = React.useState({
   input1: "",
   input2: ""
 })

  const onChange = e => {
   let localInput = {...input}; //need to create a new reference to input state
   localInput[e.target.name] = e.target.value
   setInput(localInput)
   if(typeof props.onChange === "function"){ //run the onChange callback from parent
         return props.onChange(localInput) 
     }
  }

  //validates that all values in the input state are populated
  const isValid = () => Object.keys(input).every(key => notEmptyValidation(input[key]))

  return (
      <div>
        <div><h2>User Name Control Header</h2></div>
        <InputBox
          label='First Name: '
          name='input1'
          value={input.inputValue1}
          validation={notEmptyValidation} //pass validation function down to the child
          onChange={onChange}/>
          <br/>
        <InputBox
          label='Last Name: '
          name='input2'
          value={input.inputValue2}
          validation={notEmptyValidation} //pass validation function down to the child
          onChange={onChange}/>
        <div>
           <h4>User Name Control Footer: Is section valid = {`${isValid() ? "true":"false"}`}.</h4>
        </div>
       </div>
    )

}


const EditPage = () => {
  const [userNameData, setUserNameData] = React.useState(null)

  const onChange = inputObj => setUserNameData(inputObj)

  //validates that the input was successful, and all entries are populated
  const isValid = () => userNameData && Object.keys(userNameData).every(key => notEmptyValidation(userNameData[key]))


  return (
      <form>
      <h1>Edit Form</h1>
        <div>
          <UserNameControl onChange={onChange}/>
        </div>
        <div>
          <h4>Is form valid = {`${isValid() ? "true":"false"}`}</h4>
        </div>
      </form>
    );
}

ReactDOM.render(
  <EditPage/>,
  document.getElementById('root')
);

从“React”导入React
const notEmptyValidation=value=>Boolean(值)
常量输入框=道具=>{
const{validation,label,name}=props;
const[localValue,setValue]=React.useState(props.value | | |“”);
const onChange=e=>{
设定值(即目标值);
if(公共关系类型)