将 graphQL 突变函数作为 prop 传递还是将其注入 child 组件?

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

我在 reactJS/graphQL-Application 中使用 react-apollo。 有时我确实需要对多个组件进行相同的修改。那么使用突变并在调用突变后更新数据的最佳方式是什么?

我应该在顶部组件中注入突变并将其传递给所有 children(示例 2)还是应该在需要的地方注入突变(示例 1)?

对于示例 1,在突变调用之后更容易更新现有数据,而传递 parent 组件的 doMutation() 函数使更新对我来说变得复杂。


示例 1(多次注入)

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

孙子

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)

示例 2(传递函数作为 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} />
    }
}

孙子

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

这主要归结为偏好,但避免将查询结果作为 props 传递有一些优点,即:

  • 更好的性能。避免自上而下的 prop 流程意味着减少不必要的中间组件重新渲染。
  • 更简单的数据流。无需追查道具的来源。
  • 更大的灵活性。即使两个组件最初需要相同的数据,需求也会随着时间而改变。让每个组件使用自己的挂钩意味着您可以更改传递给一个组件的挂钩的参数而不影响另一个组件。
  • 减少父子组件之间的耦合。您可以重构父组件或将子组件添加到应用的其他部分,而不必担心必须确保数据向下传递到子组件。