提供商重新渲染时,消费者重新渲染

时间:2019-01-25 07:33:32

标签: javascript reactjs

根据react docs

  

每次提供者重新渲染时,下面的代码将重新渲染所有使用者,因为总是为值创建新对象

因此,我举了一个简单的示例对此进行了测试:

class App extends React.Component {

constructor(props) {
    super(props);
    this.state = {
      value: {something: 'something'},
    };
  }
  render() {
   console.log('App');
    return (
    <>
      <ThemeContext.Provider value={this.state.value}>
      <ThemeContext.Consumer>
       {(value)=>( <Toolbar test={value}/>)}
      </ThemeContext.Consumer>
      </ThemeContext.Provider>
      <button onClick={this.handler}>click me</button>
      </>
    );
  }

  handler=()=>{
  this.forceUpdate()
  }
}

const app =  <App />;

class Toolbar extends React.Component {
  render() {
   console.log('Toolbar');
    return (
     <div></div>
    );
  }
}

ReactDOM.render(app,mountNode);

似乎每次单击,即使引用相同,工具栏组件也会随提供程序一起重新呈现。那么这是怎么了?

2 个答案:

答案 0 :(得分:1)

将使用者写为App的直接子代将导致他们在App组件重新渲染时呈现,而您必须将代码编写为

const ThemeContext = React.createContext();
class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      value: {something: 'something'},
    };
  }
  render() {
   console.log('App');
    return (
     <React.Fragment>
      <ThemeContext.Provider value={this.state.value}>
          {this.props.children}
      </ThemeContext.Provider>
      <button onClick={this.handler}>click me</button>
      </React.Fragment>
    );
  }

  handler=()=>{
    this.forceUpdate()
  }
}

const app =  (<App>
               <ThemeContext.Consumer>
                  {(value)=>( <Toolbar test={value}/>)}
                </ThemeContext.Consumer>
             </App>)

class Toolbar extends React.Component {
  render() {
   console.log('Toolbar');
    return (
     <div></div>
    );
  }
}
ReactDOM.render(app, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<div id="app"/>

答案 1 :(得分:0)

尝试一下:

class App extends React.Component {

constructor(props) {
    super(props);
    this.state = {
      value: {something: 'something'},
    };
  }

   handler(){
    this.forceUpdate()
    }

  render() {
   console.log('App');
    return (
    <div>
      <ThemeContext.Provider value={this.state.value}>
      <ThemeContext.Consumer>
       {(value)=>( <Toolbar test={value}/>)}
      </ThemeContext.Consumer>
      </ThemeContext.Provider>
      <button onClick={this.handler}>click me</button>
      </div>
    );
  }


}

const app =  <App />;

class Toolbar extends React.Component {
  render() {
   console.log('Toolbar');
    return (
     <div></div>
    );
  }
}

ReactDOM.render(app,mountNode);