0

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.usergetVariables()返回初始数据。)

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到我的后端。这是显示我的问题的屏幕截图:

未更改的用户被发送到后端

4

0 回答 0