0

所以我编写了一个提供程序来将字符串传递给我的应用程序的任何部分。我遇到的问题是,如果我向我的子组件添加一个字符串道具,它会覆盖整个道具并且似乎忽略了我在连接器中所做的合并

提供者

import { Component, Children } from 'react'
import PropTypes from 'prop-types'

export default class StringsProvider extends Component {
  static propTypes = {
    children: PropTypes.element.isRequired,
    strings: PropTypes.object
  }

  // Specify what is being added to context
  static childContextTypes = {
    strings: PropTypes.object.isRequired
  }

  getChildContext() {
    const { strings } = this.props

    return { strings: strings }
  }

  render() {
    return Children.only(this.props.children)
  }
}

连接器

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import _ from 'lodash'

// here we basically create a HOC that returns on Context (This is our component).
// The HOC adds the merged strings set to the Context Component and then renders it
export default (WrappedComp, defaultStrings, stringNameSpace) => {
  return class StringsComponent extends Component {
    static propTypes = {
      strings: PropTypes.object.isRequired
    }

    static contextTypes = {
      strings: PropTypes.object.isRequired
    }

    // Takes the defaultStrings from the context and merges them with the
    // strings passed to the Context Component
    getStrings = () => {
      let out

      if (this.props.strings) {

        console.log('defaultStrings: ' + Object.values(defaultStrings)[0])
        console.log(
          'this.context.strings[stringNameSpace]: ' +
            Object.values(this.context.strings[stringNameSpace])[0]
        )
        console.log(
          'this.props.strings: ' + Object.values(this.props.strings)[0]
        )
        out = _.merge(
          defaultStrings,
          this.context.strings[stringNameSpace] ? this.context.strings[stringNameSpace] : {},
          this.props.strings
        )
      } else {
        out = _.merge(defaultStrings, this.context.strings[stringNameSpace])
      }


      console.warn('out')
      console.log(out)
      return out
    }

    render() {
      return <WrappedComp strings={this.getStrings()}  {...this.props} />

    }
  }
}

零件

import React, { Component } from 'react'
import { connectStrings } from './../../src'
import PropTypes from 'prop-types'
import defaultStrings from './strings'

class SampleComponent extends Component {
  static propTypes = {
    strings: PropTypes.object.isRequired
  }

  render() {
    const { strings } = this.props
console.warn(strings)
    return (
      <div>
        <span>{strings.str1}</span>
        <span>{strings.str2}</span>
        <span>{strings.str3}</span>
      </div>
    )
  }
}

export default connectStrings(
  SampleComponent,
  defaultStrings,
  'sampleComponent.ui.SET_TWO'
)

单元测试运行

import renderer from 'react-test-renderer'
import React from 'react'
import { StringProvider } from '../src'
import SampleComponent from "../components/sampleComponent";
describe('String Provider Tests', () => {
  it('should render', () => {
    const strings = {
      'sampleComponent.ui.SET_ONE': {
        str1: 'SET ONE'
      },
      'sampleComponent.ui.SET_TWO': {
        str1: 'SP Str1',
        str2: 'SP Str2'
      }
    }

    const tree = renderer.create(
      <StringProvider strings={strings}>
        <SampleComponent strings={{str3: 'test'}}/>

      </StringProvider>
    )

    expect(tree).toMatchSnapshot()
  })
})

我不确定我在这里遗漏了什么,但字符串似乎在连接器中更新但在组件中没有更新,是不是我做错了什么?

4

1 回答 1

0

多么愚蠢,答案很简单,下面我只需要更改道具在包装组件中添加的顺序

return <WrappedComp strings={this.getStrings()}  {...this.props} />

似乎 this.props 还包含字符串,它覆盖了GetStrings()函数的结果。

于 2018-06-15T13:04:50.450 回答