Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.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 使用无状态组件实现表单输入验证的正确方法是什么_Javascript_Reactjs_React Native_Redux - Fatal编程技术网

Javascript 使用无状态组件实现表单输入验证的正确方法是什么

Javascript 使用无状态组件实现表单输入验证的正确方法是什么,javascript,reactjs,react-native,redux,Javascript,Reactjs,React Native,Redux,因此,我最近开始使用react native,我显然希望使用最佳实践来开发我的应用程序。这就是为什么我决定使用redux并按照建议编写无状态的功能组件 一旦我习惯了它并建立了一些标准,它就在一段时间内发挥了巨大的作用:我编写了一个功能组件,映射状态并发送到它的道具,并且有一个存储,它可以跟踪事物的状态,并由提供者注入 一旦我开始验证表单输入组件,事情就变得复杂了。假设我希望有一个组件,可以验证其输入并在出现问题时显示错误。显然,我可以为此在全局存储中添加一些状态,但我不想在全局存储中为我在应用程

因此,我最近开始使用react native,我显然希望使用最佳实践来开发我的应用程序。这就是为什么我决定使用redux并按照建议编写无状态的功能组件

一旦我习惯了它并建立了一些标准,它就在一段时间内发挥了巨大的作用:我编写了一个功能组件,映射状态并发送到它的道具,并且有一个存储,它可以跟踪事物的状态,并由
提供者注入

一旦我开始验证表单输入组件,事情就变得复杂了。假设我希望有一个组件,可以验证其输入并在出现问题时显示错误。显然,我可以为此在全局存储中添加一些状态,但我不想在全局存储中为我在应用程序中使用的每个输入设置一个位置。这可能与关于使用redux的教导形成对比,但我觉得我想要的并不是那么不切实际

举一个我想要的例子:

const Input = ({ error }) => {
  let style = styles.input;
  const onChange = (val) => {
    // change the error here, say
    if(val === 'test') error = null;
    else error = 'must be test';
  };
  if (error) {
    style = styles.inputError;
  }
  return (
    <TextInput
      style={style}
      onChangeText={onChange}
    />
  );
};
const输入=({error})=>{
让style=styles.input;
const onChange=(val)=>{
//在这里更改错误,比如
如果(val=='test')错误=null;
else错误='必须是测试';
};
如果(错误){
style=styles.inputError;
}
返回(
);
};
但我不想把错误和全局状态联系起来

这是问得太多了,还是我忽略了让
输入
刷新自身的方法(我根本无法在其中获得
这个


我明白这是一个更具哲理的问题,因为有一个显而易见的解决方案,就是为组件创建ES6类并使用
setState
。我最感兴趣的是听一些解决这个问题的方法,如果有问题,或者我太固执了

好的,我提到这几乎是一个元问题,但对我来说是一个重要的问题,因为我在处理它的过程中学到了很多

希望我学到的东西能帮助遇到同样问题的人,并节省他在网上资源很少的情况下研究这个主题所需的时间:

  • 你不能也不应该从它的内部访问你的纯控制
  • 如果您必须将控件创建为ES6类并访问
    ,那么即使您的linter也不会再抱怨了,因为这是一个很好的用例,所以有两种情况下可以扩展
    组件
  • 使用这两个结论的控件示例如下所示:

    class Input extends Component {
      render() {
        let style = styles.input;
        const error = this.state && this.state.error;
        const onChange = (val) => {
          if (val === 'test') this.setState({ error: null });
          else this.setState({ error: 'test required' });
        };
        if (error) {
          style = styles.inputError;
        }
        return (
          <TextInput
            style={style}
            onChangeText={onChange}
          />
        );
      }
    }
    

    我仍然希望听到关于这些的其他方法和评论。谢谢。

    在父级非功能组件中使用react state是解决方案吗?否则,如果您想控制输入,就不应该使用功能组件。我没有非功能组件。如果我想控制输入,是否有理由不使用功能组件?如果我想让家长设置我的组件输入怎么办?有没有一种方法可以在保持父级功能的同时实现这一点。保持你的状态,2。有一个非功能组件,该组件对状态和onChange处理程序进行反应,3。只在提交时验证输入,不像您在onChange={myHandler}有效点上做的那样,所以最简单的方法是让ES6类控制自己的状态并使用它。不幸的是,在提交时不能进行输入验证。因此,是的,你应该使用非功能性的方法进行验证,这种方法在性能方面没有太多遗漏。我是同一个决策分支,尽管我喜欢你的想法,但听到其他案例也会很有趣。嗯,有趣的评论,不幸的是,可能没有很多人会偶然发现这一点,所以我已经发送了我未来的自我,给您第二个意见:事实可能是您希望您的常用组件最终无状态。因此,即使您的输入本身是哑的,它也会将所有内容传递给它。你绝对需要有一个有状态的父组件(所以你应该忽略我上面的固执)。在上面的一个示例中,父组件将是表单。它将处理哑输入组件呈现内容背后的逻辑。不是很深入的解释,但我希望它有意义。我同意,谢谢你的评论。没有其他答案,但我投票赞成这个问题,因为我喜欢这个思路。接下来就是。
    const localStore = createStore(
      (state = [], obj) => (obj ? { errorMessage: obj.error } : state),
      { errorMessage: null },
    );
    
    const inputWithStore = ({ error }) => {
      let style = styles.input;
      const onChange = (val) => {
        if (val === 'test') localStore.dispatch({ type: 'unused', error: null });
        else localStore.dispatch({ type: 'unused', error: 'test required' });
      };
      if (error) {
        style = styles.inputError;
      }
      return (
        <TextInput
          style={style}
          onChangeText={onChange}
        />
      );
    };
    
    const mapStateToProps = (state) => ({ error: state.errorMessage });
    
    const InputWithStore = connect(mapStateToProps)(inputWithStore);
    
    const Input = () =>
    (
      <Provider store={localStore}>
        <InputWithStore />
      </Provider>
    );