2

我坚持传递从突变返回的数据来处理 Reactjs 中的表单验证。此模式不仅限于表单验证,还适用于其他具有相似要求的组件,其中某些内容发生了变异/查询,并且响应数据仅用于更新 UI。

概念:

<LoginForm/>组件呈现登录表单并提交loginMutation表单数据。验证发生在后端,如果验证捕获到任何错误,突变将使用errors包含键值对的字段来解决,其中键代表表单字段,值描述值的问题。这个想法是将errors对象传递给 ,<LoginForm/>以便组件可以渲染/更新以在 UI 中显示错误。

errors: { 
  username: "Username must not be empty", 
  password: "Password must not be empty"
}

挑战:

应该以什么方式将解析的数据(errors)传递给<LoginForm/>?最直接的锤钉方法是将回调函数传递给loginMutationfrom并在响应对象<LoginForm/>中调用它。onComplete()像这样的东西:

onCompleted: (response, errors) => { setLoginFormState(resonse.errors) }

然后在<LoginForm/>里面会有

setLoginFormState(validationState){ 
    this.setState({errors: validationState })
}

最后我们可以<LoginForm/>像这样相应地更新 UI

render(){
  const { errors } = this.state;
  const usernameClass = errors.username ? 'danger' : 'primary';
  const passwordClass = errors.password ? 'danger' : 'primary';
  return (
    <div>
      <input name="username" className={usernameClass} />
     <input name="username" className={passwordClass} />
    </div>
  )

}

我正在寻找一种不太重要的方法来减少意大利面。

此外,我期待已宣布的架构扩展功能,该功能目前缺少文档。似乎它的目的是通过允许我们将本地状态(例如 UI 状态)与从查询/突变中获取的持久数据混合来解决这个问题。

4

1 回答 1

-1

React-Relay-Rebind是 Relay 现代和 React 的组件范围状态管理。

我创建了这个库来提供一个声明性 API 来管理由 Relay 突变返回的本地状态。该库目前正在积极开发中。欢迎打开新问题并提交 PR!

React-Relay-Rebind 允许您将突变绑定到组件。绑定意味着组件将接收突变返回的状态作为道具。

使用示例

import { rebind } from 'react-relay-rebind';
import { loginMutation } from './loginMutation';

class MyComponent extends React.component {

  handleSubmit(){
    this.props.mutations.login(this.props.relay, this.state);
  }

  handleFieldChange(fieldName){
    return (e) => {
      // Login mutation stateProxy
      const { login } = this.props;

      this.setState({ [fieldName]: e.target.value() });

      // Set login mutation to initial state
      this.login.resetState();
    }
  }

  render(){
    const { errors } = this.props.login.state;
    const usernameClassname = errors.username ? 'has-error' : '';
    const passwordClassname = errors.password ? 'has-error' : '';

    return (
       <div>
        <input
          className={usernameClassname}
          name="username"
          type="text"
          onChange={this.handleFieldChange('username')}
          value={username} />
        <br/>
        <input
          className={passwordClassname}
          name="password"
          type="password"
          onChange={this.handleFieldChange('password')}
          value={password} />
        <br/>
        <input type="submit" onClick={this.handleSubmit} value="Login"/>
      </div>
  }
}

const mutations = {
  login: {
    mutation: LoginMutation,
    initialState: {
      errors: {
        username: null,
        password: null,
      },
    },
  },
};
export default rebind(mutations)(MyComponent);
于 2017-11-04T23:32:39.347 回答