Relay.Mutation

Relay 利用 GraphQL mutations; 使我们能够在客户端和服务器上变更数据的操作。要建立一个 mutation 在我们的应用程序中使用,我们必须继承 Relay.Mutation 并至少实现在下面的四个 抽象方法。

概述 #

属性

方法

属性 #

fragments (静态属性) #

static fragments: RelayMutationFragments<$Keys<Tp>>

// Type of RelayMutationFragments
type RelayMutationFragments<Tk> = {
  [key: Tk]: FragmentBuilder;
};

// Type of FragmentBuilder
type FragmentBuilder = (variables: Variables) => RelayConcreteNode;

我们在这里声明我们的 mutations 数据依赖关系,就像我们用容器一样。这对于用来确保我们可能会想要在这个 mutation 的积极响应中使用的一组字段已经被获取特别有用。

示例 #

class LikeStoryMutation extends Relay.Mutation {
  static fragments = {
    story: () => Relay.QL`
      fragment on Story {
        likers { count },
        viewerDoesLike,
      }
    `,
  };
  getOptimisticResponse() {
    // this.props.story.likers.count and this.props.story.viewerDoesLike
    // are guaranteed to have been fetched since we've declared
    // them to be part of this mutation's data dependencies above.
    return { /* ... */ };
  }
}

参见: Mutations > Fragment 变量 and Mutations > 积极更新

initialVariables (静态属性) #

static initialVariables: {[name: string]: mixed};

我们在这里指定的默认值将可用于我们的片段构建:

示例 #

class ChangeTodoStatusMutation extends Relay.Mutation {
  static initialVariables = {orderby: 'priority'};
  static fragments = {
    todos: () => Relay.QL`
      # The variable defined above is available here as $orderby
      fragment on User { todos(orderby: $orderby) { ... } }
    `,
  };
  /* ... */
}

参阅: Mutations > Fragment 变量

prepareVariables (静态属性) #

static prepareVariables: ?(
  prevVariables: {[name: string]: mixed},
  route: RelayMetaRoute,
) => {[name: string]: mixed}

// Type of `route` argument
type RelayMetaRoute = {
  name: string;
}

如果我们提供给 mutation 一个方法符合上面所描述的 signature,它会有一个机会基于先前的变量 (或是如果前面没有的话会是 initialVariables )、meta 路由、和执行期环境,去调整 fragment 构建的变量。无论这个方法回传什么变量都会可以在这个 mutation 的 fragment 构建取用。

示例 #

class BuySongMutation extends Relay.Mutation {
  static initialVariables = {format: 'mp3'};
  static prepareVariables = (prevVariables) => {
    var overrideVariables = {};
    var formatPreference = localStorage.getItem('formatPreference');
    if (formatPreference) {
      overrideVariables.format = formatPreference;  // Lossless, hopefully
    }
    return {...prevVariables, overrideVariables};
  };
  /* ... */
}

参阅: Mutations > Fragment 参数

方法 #

构造函数 #

使用 new 关键词建立一个 mutation 实例,可选地传递给它一些 this.props。要注意的是,this.props 在 函数里面是不可取用的,不过在所有下面提到的方法 (getCollisionKey、getOptimisticResponse,等等) 都是设置好的。 这种限制是由于 mutation props 可能取决于 Relay 环境的数据,直到 mutation 应用于 applyUpdatecommitUpdate

示例 #

var bookFlightMutation = new BuyPlaneTicketMutation({airport: 'yvr'});
Relay.Store.commitUpdate(bookFlightMutation);

getConfigs (抽象方法) #

abstract getConfigs(): Array<{[key: string]: mixed}>

实现这个必要的方法来给出 Relay 指令,说明如何使用每个 mutation 的响应有效载荷来更新客户端存储。

示例 #

class LikeStoryMutation extends Relay.Mutation {
  getConfigs() {
    return [{
      type: 'FIELDS_CHANGE',
      fieldIDs: {
        story: this.props.story.id,
      },
    }];
  }
}

参阅: Mutations > Mutator 配置

getFatQuery (抽象方法) #

abstract getFatQuery(): GraphQL.Fragment

实现这个必要的方法来设计一个 ‘fat 查询’ – 代表数据模型中可能由于这种 mutation 而改变的每个字段。

示例 #

class BuySongMutation extends Relay.Mutation {
  getFatQuery() {
    return Relay.QL`
      fragment on BuySongPayload {
        songs {
          count,
          edges,
        },
        totalRunTime,
      }
    `,
  }
}

参阅: Mutations > fat 查询

getMutation (抽象方法) #

abstract getMutation(): GraphQL.Mutation

实现必要的方法来返回表示要执行的突变的GraphQL mutation 操作。

示例 #

class LikeStoryMutation extends Relay.Mutation {
  getMutation() {
    return this.props.story.viewerDoesLike
      ? return Relay.QL`mutation {unlikeStory}`
      : return Relay.QL`mutation {likeStory}`;
  }
}

getVariables (抽象方法) #

abstract getVariables(): {[name: string]: mixed}

实现这个必要的方法来准备变量作为 mutation 的输入。

示例 #

class DestroyShipMutation extends Relay.Mutation {
  getVariables() {
    return {
      // Assume that the server exposes a `destroyShip` mutation
      // that accepts a `shipIDToDestroy` variable as input:
      shipIDToDestroy: this.props.ship.id,
    };
  }
}

警告

这里的术语“变量”是指对服务器端 mutation 的输入,而不是这个 mutation 的片段构建可用的变量。

getFragment (静态方法) #

static getFragment(
  fragmentName: $Keys<Tp>,
  variableMapping?: Variables
): RelayFragmentReference

// Type of the variableMapping argument
type Variables = {[name: string]: mixed};

获取用于父查询片段的片段引用。

示例 #

class StoryComponent extends React.Component {
  /* ... */
  static fragments = {
    story: () => Relay.QL`
      fragment on Story {
        id,
        text,
        ${LikeStoryMutation.getFragment('story')},
      }
    `,
  };
}

您还可以从包含它的外部片段将变量传递给 mutation 的片段构建器。

class Movie extends React.Component {
  /* ... */
  static fragments = {
    movie: (variables) => Relay.QL`
      fragment on Movie {
        posterImage(lang: $lang) { url },
        trailerVideo(format: $format, lang: $lang) { url },
        ${RentMovieMutation.getFragment('movie', {
          format: variables.format,
          lang: variables.lang,
        })},
      }
    `,
  };
}

提示

在最后的一个例子中,把$formatvariables.format 想成是一样的值。

getCollisionKey #

getCollisionKey(): ?string

实现此方法返回冲突键。Relay 将向服务器发送具有相同冲突密钥的任何突变顺序和顺序。

示例 #

class LikeStoryMutation extends Relay.Mutation {
  getCollisionKey() {
    // Give the same key to like mutations that affect the same story
    return `like_${this.props.story.id}`;
  }
}

getFiles #

getFiles(): ?FileMap

// Type of the FileMap object
type FileMap = {[key: string]: File};

实现这个方法来回传一个要上传的 File 对象的映射作为 mutation 的一部份。

示例 #

class AttachDocumentMutation extends Relay.Mutation {
  getFiles() {
    return {
      file: this.props.file,
    };
  }
}
class FileUploader extends React.Component {
  handleSubmit() {
    var fileToAttach = this.refs.fileInput.files.item(0);
    Relay.Store.commitUpdate(
      new AttachDocumentMutation({file: fileToAttach})
    );
  }
}

getOptimisticConfigs #

getOptimisticConfigs(): Array<{[key: string]: mixed}>

在需要处理积极响应的mutator 配置需要与处理服务器响应的 mutator 配置不同的实现方法。

参阅: Relay.Mutation::getConfigs()

getOptimisticResponse #

getOptimisticResponse(): ?{[key: string]: mixed}

实现此方法来制作与服务器响应有效负载相同情形的积极响应。这种积极的响应将用于在服务器返回之前抢先更新客户端缓存,从而给出瞬时完成 mutation 的印象。

示例 #

class LikeStoryMutation extends Relay.Mutation {
  getOptimisticResponse() {
    return {
      story: {
        id: this.props.story.id,
        likers: {
          count: this.props.story.likers.count + 1,
        },
        viewerDoesLike: !this.props.story.viewerDoesLike,
      },
    };
  }
}

参阅: Mutations > 积极更新