如何创建共享功能但具有独立状态的反应组件?

时间:2016-08-30 05:39:07

标签: javascript reactjs

我想创建两个React组件。他们需要分享共同的功能。这些函数使用this.setState(),所以我无法将它们放在辅助文件中。我尝试使用composition。这使我能够共享功能,但他们也共享状态。

我需要像

这样的东西
//file 1
var Component1 = React.createClass({
    getInitialState() {
        return {
            //return some common + new states
        }
});

//file 2
var Component2 = React.createClass({
    getInitialState() {
        return {
            //return some common + new states
        }
});

// file 3
// This file needs to have some functions, which can do:
this.setState(); //on state of Component1 and Component2.

2 个答案:

答案 0 :(得分:2)

你有几个选择。

商店

如果这些组件完全独立,您可以使用商店来保存和更新每个组件使用的数据,并订阅商店。这是Flux / Redux模式。

组件可能看起来像这样

const store = {
  subscriptions: new Set(),
  data: {},
  subscribe: function (callback) {
    this.subscriptions.add(callback)
  },
  unsubscribe: function (callback) {
    this.subscriptions.delete(callback)
  },
  update: function (key, value) {
    this.data[key] = value
    this.subscriptions.forEach(cb => cb(this.data))
  }
}

这里要注意的是商店没有直接访问组件的状态。组件订阅,其他一些机制将发布数据。如果发生这种情况,商店将调用已注册的回调。 非常 简单商店可能看起来像这样

const CounterButton = () => (
  <button onClick={() => store.update('count', (store.data.count || 0) + 1)}>Increase Count</button>
)

这允许任何有权访问商店的人更新订阅它的任何/所有组件。

props

这是一个非常contrived codepen来证明这个

父组件

如果您的组件都是共享组件的子组件,那么他们的父组件可以通过更新其class ParentComponent extends React.Component { constructor(...props) { super(...props) this.state = { clicks: 0 } } render () { return ( <div> <button onClick={() => this.setState({ clicks: this.state.clicks + 1})}>Increase Count</button> <Component1 clicks={this.state.clicks} /> <Component2 clicks={this.state.clicks} /> </div> ) } } const Component1 = ({clicks}) => ( <span>You have clicked {clicks} times</span> ) const Component2 = (props) => ( <span>You have pressed {props.clicks} times</span> ) 来更新它们,而不是更新其状态。它可以使用自己的内部状态来跟踪它。

var sharedComponents = new Set()

function incrementComponents () {
  sharedComponents.forEach(c => c.setState({clicks: c.state.clicks + 1}))
}

class Component1 extends React.Component {
  constructor(...props) {
    super(...props)
    this.state = { clicks: 0 }
    sharedComponents.add(this)
  }

  render () {
    return (<span>You have clicked {this.state.clicks} times</span>)
  }
}

setInterval(incrementComponents, 1000)

以下是展示此

equally contrived codepen

某事疯狂其他

以上两种是推荐的方式。但这是JavaScript,我们的规则比Wild West少。如果你真的想直接控制来自某个共享函数的组件状态,那么没有什么能阻止你

s

这是一个completely insane codepen来证明这一点。

答案 1 :(得分:1)

保持Component1和&amp; Component2下的Parent component,如果您将父组件功能传递给子组件,则Component1&amp; Component2Parent Component函数设为props。因此,您可以像common那样获得parent-child relationship函数,因为反应组件可以在word_count = defaultdict(int) for line in fileinput.input([file]): line = line.strip() words = line.split() for word in words: word_count[word] += 1 中运行。孩子们可以从他们的父母那里获得数据。这样你的所有子组件也都有自己的状态。