0

I want to skip rendering of container, but run rendering and reconciliation for the childeren passed via props. In the next example you can click it and see

render
render2
render value 2001
render value 3001

but I want it to be

render
render value 1001
render2
render value 2001
render value 3001

So I want Value 1001 to render, but without rendering Wrapper1.

How can I do that?

class Value extends React.Component {
  render() {
    console.log("render value " + this.props.value);
    return this.props.value;
  }
}

class Wrapper1 extends React.Component {
  shouldComponentUpdate() {
    return false;
  }

  render() {
    console.log("render1");
    return this.props.children;
  }
}

class Wrapper2 extends React.PureComponent {
  render() {
    console.log("render2");
    return this.props.children;
  }
}

class App extends React.Component {
  state = { count: 0 };

  render() {
    console.log("render");
    return (
      <div onClick={() => this.setState(({ count }) => ({ count: count + 1 }))}>
        <Wrapper1><Value value={1000 + this.state.count} /></Wrapper1>
        {" "}
        <Wrapper2><Value value={2000 + this.state.count} /></Wrapper2>
        {" "}
        <Value value={3000 + this.state.count} />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.querySelector("main"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<main></main>
Qwertiy
  • 19,681
  • 15
  • 61
  • 128
  • Why do you need `Wrapper1`? And why do you want to skip rendering it? Check https://stackoverflow.com/questions/30626030/can-you-force-a-react-component-to-rerender-without-calling-setstate – UjinT34 Nov 26 '18 at 14:20

2 Answers2

1

To rerender children without rerendering Wrapper1 you need to change their state somehow. Note that props of Value inside Wrapper1 never change. So forced renders will output the same value unless you pass it some other way. There is some bad code for example:

class Value extends React.Component {
  state = {value: null};

  componentDidMount() {
    if (typeof(this.props.setUpdater) === 'function') this.props.setUpdater(
      value => this.setState({value})
    );
  }

  render() {
    console.log("render value ", this.state.value, this.props.value);
    return this.state.value || this.props.value;
  }
}

class Wrapper1 extends React.Component {
  shouldComponentUpdate() {
    return false;
  }

  render() {
    console.log("render1");
    return this.props.children;
  }
}

class Wrapper2 extends React.PureComponent {
  render() {
    console.log("render2");
    return this.props.children;
  }
}

class App extends React.Component {
  state = { count: 0 };

  render() {
    console.log("render");
    if (typeof(this.state.updater) === 'function') this.state.updater(1000 + this.state.count);
    return (
      <div onClick={() => this.setState(({ count }) => ({ count: count + 1 }))}>
        <Wrapper1><Value value={1000 + this.state.count} setUpdater={updater => this.setState({updater})}/></Wrapper1>
        {" "}
        <Wrapper2><Value value={2000 + this.state.count} /></Wrapper2>
        {" "}
        <Value value={3000 + this.state.count} />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.querySelector("main"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<main></main>
UjinT34
  • 4,784
  • 1
  • 12
  • 26
0

Try using shouldComponentUpdate

Fawzi
  • 359
  • 2
  • 12