TL;DR: 在阅读了有关 React 和 Relay 的各种资源并使用 react-relay 构建原型应用程序后,我遇到了一个没有帮助就无法解决的问题。这是关于如何告诉突变要保存哪些数据。
我有一个显示User
实体详细信息的组件。它是通过中继查询加载的。该组件有一个<input />
包含用户名的字段和一个触发relay.commitUpdate(...)
调用的保存按钮。每当我在输入字段中更改用户的名称并单击保存时,我可以看到不是更改的而是原始名称被发送到后端。
我正在构建一个应用程序,react-relay
并且我正在开发一个组件,该组件应该显示有关user
实体的详细信息,并且可以更改这些数据并保存它。它是Master-Detail-Pattern的细节部分。
加载和更改数据工作正常。但是更改不会提交到后端。对于数据更新,我正在尝试使用中继突变。
单击保存后,我可以在我的 chrome 浏览器的开发人员控制台中看到,未更改的数据已发送到我的后端。我想念什么?这是我到目前为止所拥有的(Typescript 代码)。
onSaveClick()
(更新:在组件的方法和突变中的方法中放置断点时getVariables()
,我看到在onSaveClick
属性this.props.user
中包含所做的更改,而this.props.user
在getVariables()
返回初始数据。)
export interface IUserDetailsProps { user: User }
export interface IUserDetailsStates { user: User }
class UserDetails extends React.Component<IUserDetailsProps, IUserDetailsStates> {
constructor(props: IUserDetailsProps) {
super(props);
this.state = { user: this.props.user };
}
public onFirstNameChange(event: any) {
let user = this.state.user;
this.state.user.firstName = event.target.value;
this.props.user.firstName = event.target.value; // is this needed?
this.setState({ user: user });
}
public onSaveClick() {
this.props.relay.commitUpdate(new UserMutation({ user: this.props.user }));
}
public render(): JSX.Element {
let user: User = this.props.user;
return <div>
<input type="text" value={user.firstName} onChange={this.onFirstNameChange.bind(this)} />
<button onClick={this.onSaveClick}>Save</button>
</div>;
}
}
class UserMutation extends Relay.Mutation {
public getMutation() {
return Relay.QL`mutation {saveUser}`;
}
public getVariables() {
return this.props.user;
}
public getFatQuery() {
return Relay.QL`
fragment on UserPayload {
user {
id,
firstName
}
}
`;
}
public getConfigs() {
return [{
type: "FIELDS_CHANGE",
fieldIDs: {
user: this.props.user.id
}
}];
}
static fragments = {
user: () => Relay.QL`
fragment on User {
id,
firstName
}
`
}
}
export default Relay.createContainer(UserDetails, {
fragments: {
user: () => Relay.QL`
fragment on User {
id,
firstName,
${UserMutation.getFragment("user")}
}
`
}
});
解决方案尝试:
我将用户名字的输入字段的行更改为:
<input type="text"
ref={(ref) => {
this.myTextBox = ref;
ref.value = this.props.user.firstName;
}} />
并删除了更改事件处理程序并删除了所有state
代码。
我的点击处理程序现在看起来像这样:
public onSaveClick() {
let user = Object.assign({}, this.props.user);
user.firstName = this.myTextBox.value;
this.props.relay.commitUpdate(new UserMutation({user: user}));
}
我可以看到,传递给突变的用户对象现在具有firstName
我在文本输入中更改的新值。但同样,中继将未更改的内容发送user
到我的后端。这是显示我的问题的屏幕截图: