React上下文组件渲染

时间:2018-08-31 14:28:20

标签: javascript reactjs

我在使用上下文渲染组件时遇到问题。 AppProvider类具有一个名为add的函数,该函数可更改状态。 我正在使用上下文将add函数和状态传递给组件。 每当组件上发生Onclick事件时,add方法都会设置新状态。

所以我的问题是,当在任一组件上发生onclick时,状态都会改变。那么,为什么更改没有同时反映在两个组件上?

当我在console.log(this.state)函数中add时。组件已使用相同的状态值初始化,但是两个组件都维护自己的状态实例。

似乎AppProvider每次调用都传递一个新实例。 它应该以这种方式表现吗?如何使用上下文共享同一实例的不同组件。

import React from "react";           
import ReactDOM from "react-dom";

var Mycontext=React.createContext();

class AppProvider extends React.Component {
  constructor(props) {
   super(props)
   this.state=({ total:12323 }) 
  } 

  add(){
   var x=this.state.total
   x++;
   this.setState({total:x})
  } 

  render() {
   return (
    <div>
     <Mycontext.Provider 
      value = {{add:this.add.bind(this),state:this.state.total}}>
      {this.props.children}
     </Mycontext.Provider>
    </div>
   )
  }      
}

var ContextConsumer = Mycontext.Consumer;

var Para2=(props) => {
 console.log(props)
 return (<p onClick={()=>props.add()}>{props.data}</p>)
}

var Para1=(props) => {
 return (<p onClick={()=>props.add()}>{props.data}</p>)
}

var App=(props) => {
 return (
  <div>
   <AppProvider>
    <ContextConsumer>
     {({state,add}) => <Para1 data={state} add={add}/>}
    </ContextConsumer>
   </AppProvider>
   <AppProvider>
    <ContextConsumer>
     {({state,add}) => <Para1 data={state} add={add} />
    </ContextConsumer>
   </AppProvider>
  </div>
  )
 }

 ReactDOM.render(<App/>,document.getElementById("index"));

@CameronDowner假设组件嵌套在div内,并且不是使用AppProvider的直接同级组件,只是在这种情况下一次不起作用。

当组件不是直接同级时,如何传递AppProvider的单个实例?这可能吗?

<div class="container">
  <div class="row">
    <AppProvider>
      <div class="col m6 s6 l6">
        <ContextConsumer>
          {({ state, add }) =>
          <Para1 data={state} add={add}/>}
        </ContextConsumer>
      </div>
      <div class="col m6 s6 l6">
        <ContextConsumer>
          {({ state, add }) =>
          <Para2 data={state} add={add} /> }
        </ContextConsumer>
      </div>
    </AppProvider>
  </div>
</div>

1 个答案:

答案 0 :(得分:1)

正如@Dave Newton在评论中提到的那样,您的代码很难理解,实际上包含一些语法错误。当问题的代码干净时,总是很容易获得帮助。

尽管如此,我还是设法找到了问题。原因是您有两个<AppProvider />组件。

  <AppProvider>
    <ContextConsumer>
      {({ state, add }) => <Para1 data={state} add={add} />}
    </ContextConsumer>
  </AppProvider>
  <AppProvider>
    <ContextConsumer>
      {({ state, add }) => <Para2 data={state} add={add} /> }
    </ContextConsumer>
  </AppProvider>

这意味着有两种状态,它们分别传递给每个组件。

如果像这样用一个替换它,则您的组件将共享一个状态,因此两个状态都将更新。

  <AppProvider>
    <ContextConsumer>
      {({ state, add }) => <Para1 data={state} add={add} />}
    </ContextConsumer>
    <MyContext.Consumer>
      {({ state, add }) => <Para2 data={state} add={add} /> }
    </ContextConsumer>
  </AppProvider>