首页 > 解决方案 > 仅在子级上运行渲染和协调器

问题描述

我想跳过容器的渲染,但对childeren传递的 via运行渲染和协调props。在下一个示例中,您可以单击它并查看

render
render2
render value 2001
render value 3001

但我希望它是

render
render value 1001
render2
render value 2001
render value 3001

所以我想Value 1001渲染,但没有渲染Wrapper1

我怎样才能做到这一点?

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>

标签: reactjs

解决方案


要在不重新渲染的情况下重新渲染孩子,Wrapper1您需要以某种方式更改他们的状态。请注意,props内部Value永远Wrapper1不会改变。所以强制渲染将输出相同的值,除非你以其他方式传递它。有一些不好的代码,例如:

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>


推荐阅读