Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/468.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何创建共享功能但具有独立状态的react组件?_Javascript_Reactjs - Fatal编程技术网

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

Javascript 如何创建共享功能但具有独立状态的react组件?,javascript,reactjs,Javascript,Reactjs,我想创建两个组件。它们需要共享共同的功能。这些函数使用this.setState(),因此我无法将它们放在帮助文件中。我试着使用组合。这使我能够共享函数,但它们也共享状态 我需要像这样的东西 //file 1 var Component1 = React.createClass({ getInitialState() { return { //return some common + new states } }); //file

我想创建两个组件。它们需要共享共同的功能。这些函数使用
this.setState()
,因此我无法将它们放在帮助文件中。我试着使用
组合
。这使我能够共享函数,但它们也共享状态

我需要像这样的东西

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

组件1
组件2
都放在
父组件
下,如果将父组件函数传递给子组件,则这两个
组件1
组件2
都将具有
父组件
作为
道具的功能。因此,当react组件在父-子关系中工作时,您可以这样获得您的
公共
函数。孩子们可以从他们的父母那里得到数据。这样,所有子组件也都有自己的状态。

这里有几个选项

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

组件可能如下所示

class Component1 extends React.Component {
  constructor(...props) {
    super(...props)
    this.update = this.update.bind(this)
    this.state = { count: 0 }
  }

  update (storeData) {
    this.setState(storeData)
  }

  componentDidMount () {
    store.subscribe(this.update)
  }

  componentDidUnmount () {
    store.unsubscribe(this.update)
  }

  render () {
    return (<span>You have clicked {this.state.count} times</span>)
  }
}
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>
)
这里有一个例子来证明这一点

还有什么疯狂的事吗 以上两个是推荐的方法。但这是JavaScript,我们的规则比狂野的西部少。如果您真的想从某个共享函数直接控制组件的状态,那么没有任何东西可以阻止您

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)
var sharedComponents=new Set()
函数增量组件(){
forEach(c=>c.setState({clicks:c.state.clicks+1}))
}
类Component1扩展了React.Component{
构造函数(…道具){
超级(…道具)
this.state={clicks:0}
sharedComponents.add(此)
}
渲染(){
返回(您已单击{this.state.clicks}次)
}
}
setInterval(增量组件,1000)

这里有一个例子来证明这一点

是的,但是这个父函数必须能够改变子状态,我认为情况并非如此。我使用的是这样的东西,因为有很多与状态相关的常用函数。您使用redux的解决方案可以工作,但我在我的应用程序中没有使用redux。第二种解决方案在这种情况下不起作用,因为我试图在完全不同的位置使用component1和component2。我目前正在使用
mixins
来解决这个问题。我知道它已被弃用,但我无法使用高阶组件创建相同的组件。我的第一个解决方案不需要redux,redux只是该模式的成熟实现。我提供了一个功能齐全的微型商店,您可以复制/粘贴并在应用程序中使用。
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)