user3142695
user3142695

Reputation: 17352

Pass graphQL mutation function as prop or inject it into child component?

I'm using react-apollo in my reactJS/graphQL-Application. Sometimes I do need the same mutation for multiple components. So what is the best way to use mutations and updating the data after calling the mutations?

Should I inject the mutation in the top component and pass it down to all children (example 2) or should I inject the mutation everywhere it is needed (example 1)?

With example 1 it is easier to update the existing data after the mutation call, while passing the doMutation()-function of parent component makes the updating mor complicating for me.


Example 1 (multiple injection)

Parent

import React, { Component } from 'react'
import { graphql } from 'react-apollo'
import { Button } from 'semantic-ui-react'
import Child from './Child'
import { MUTATION } from 'graphql/'

export class Parent extends Component {
    doMutation (event, { name, value }) {
        const { someMutation } = this.props
        return someMutation({
            variables: {
                value
            }
        })
    }

    render () {
        const { data } = this.props

        return (
            <>
                <Button onClick='this.doMutation.bind(this')>Click me to manipulate data</Button>
                <Child data={data} />
            </>
        )
    }
}
export default graphql(MUTATION, { name: 'someMutation' })(Parent)

Cild

import React, { Component } from 'react'
import GrandChild from './GrandChild'

export default class Child extends Component {
    render () {
        return <GrandChild data={this.props.data} />
    }
}

GrandCild

import React, { Component } from 'react'
import { graphql } from 'react-apollo'
import { Button } from 'semantic-ui-react'
import { MUTATION } from 'graphql/'

export class GrandChild extends Component {
    doMutation (event, { name, value }) {
        const { someMutation } = this.props
        return someMutation({
            variables: {
                value
            }
        })
    }

    render () {
        const { data } = this.props

        return (
            <Button onClick='this.doMutation.bind(this')>Click me to manipulate data</Button>
        )
    }
}
export default graphql(MUTATION, { name: 'someMutation' })(GrandChild)

Example 2 (passing function as prop)

Parent

import React, { Component } from 'react'
import { graphql } from 'react-apollo'
import { Button } from 'semantic-ui-react'
import Child from './Child'
import { MUTATION } from 'graphql/'

export class Parent extends Component {
    doMutation (event, { name, value }) {
        const { someMutation } = this.props
        return someMutation({
            variables: {
                value
            }
        })
    }

    render () {
        const { data } = this.props

        return (
            <>
                <Button onClick='this.doMutation.bind(this')>Click me to manipulate data</Button>
                <Child doMutation={this.doMutation.bind(this)} data={data} />
            </>
        )
    }
}
export default graphql(MUTATION, { name: 'someMutation' })(Parent)

Cild

import React, { Component } from 'react'
import GrandChild from './GrandChild'

export default class Child extends Component {
    render () {
        return <GrandChild doMutation={this.props.doMutation} data={this.props.data} />
    }
}

GrandCild

import React, { Component } from 'react'
import { graphql } from 'react-apollo'
import { Button } from 'semantic-ui-react'
import { MUTATION } from 'graphql/'

export default class GrandChild extends Component {
    render () {
        const { doMutation } = this.props

        return (
            <Button onClick='doMutation.bind(this')>Click me to manipulate data</Button>
        )
    }
}

Upvotes: 1

Views: 1848

Answers (1)

Daniel Rearden
Daniel Rearden

Reputation: 84787

This mostly comes down to preference, but there are some advantages to avoiding passing down the query results as props, namely:

  • Better performance. Avoiding a top-down prop flow means fewer unnecessary re-renders of middle components.
  • Simpler data flow. No need to trace where the props are coming.
  • More flexibility. Even if two components need the same data initially, requirements change over time. Having each component use their own hook means you can change the parameters passed to the hook for one component without affecting the other.
  • Less coupling between the parent and child components. You can refactor the parent or add the child component to other parts of your app without worrying about having to ensure the data is passed down to the child component.

Upvotes: 2

Related Questions