我坚持传递从变异返回的数据来处理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>
)
}
这样的
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状态)与从查询/突变中提取的持久数据混合来解决这个问题。
答案 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);