简体   繁体   中英

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>
        )
    }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM