在Relay Modern中处理本地数据

时间:2017-10-30 13:52:03

标签: reactjs relay relaymodern react-relay

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

概念:

<LoginForm/>组件呈现登录表单并使用表单数据提交loginMutation。验证发生在后端,如果验证发现任何错误,则突变将通过字段errors解析,字段errors包含键值对,其中key表示表单字段,值表示值的错误。我们的想法是将<LoginForm/>对象传递给errors: { username: "Username must not be empty", password: "Password must not be empty" } ,以便组件可以呈现/更新以在UI中显示错误。

errors

挑战:

应该以何种方式将已解析的数据(<LoginForm/>)传递给loginMutation?最直接的锤钉方法是将回调函数从<LoginForm/>传递给onComplete(),并使用响应对象在onCompleted: (response, errors) => { setLoginFormState(resonse.errors) } 内调用它。像这样:

<LoginForm/>

然后在setLoginFormState(validationState){ this.setState({errors: validationState }) } 中会有

<LoginForm/>

最后,我们可以在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
USE `rea`;
CREATE DEFINER=`root`@`localhost` PROCEDURE `Users.Update`(
    IN _UpdatedColumns VARCHAR(1000),
    IN _UserId INT UNSIGNED,
    IN _Username VARCHAR(32),
    IN _Password BINARY(64),
    IN _FullName NVARCHAR(254))
BEGIN
    UPDATE Users
    SET
        Username = CASE WHEN _UpdatedColumns LIKE '%[Username]%' THEN _Username ELSE Username END,
        Password = CASE WHEN _UpdatedColumns LIKE '%[Password]%' THEN _Password ELSE Password END,
        FullName = CASE WHEN _UpdatedColumns LIKE '%[FullName]%' THEN _FullName ELSE FullName END
    WHERE   UserId = _UserId;
END;

我正在寻找一种不那么迫切的方法来减少意大利面。

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

1 个答案:

答案 0 :(得分:-1)

React-Relay-Rebind是Relay modern&amp; amp;组件范围的状态管理。反应。

我已创建此库以提供声明性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);