Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.0k views
in Technique[技术] by (71.8m points)

react jsx和{props.children}渲染的区别?

https://codesandbox.io/s/nift... 沙箱
为什么使用{props.children}父组件更改状态子组件不会触发render?

const ComA = () => {
  console.log("ComA render");
  return <div>ComA</div>;
};

const ComB = () => {
  console.log("ComB render");
  return <div>ComB</div>;
};

function App(props) {
  console.log("App render");
  const [text, setText] = useState("text");
  return (
    <div className="App">
      <ComA />
      <ComB />
      <button onClick={setText.bind(null, "update_text"+Math.random())}>
        updateText({text})
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

打印:
App render
ComA render
ComB render

const ComA = () => {
  console.log("ComA render");
  return <div>ComA</div>;
};

const ComB = () => {
  console.log("ComB render");
  return <div>ComB</div>;
};
function App(props) {
  console.log("App render");
  const [text, setText] = useState("text");
  return (
    <div className="App">
      {props.children}
      <button onClick={setText.bind(null, "update_text" + Math.random())}>
        updateText({text})
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <App>
    <ComA />
    <ComB />
  </App>,
  rootElement
);

打印:
App render


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

整理一下你的结论:
情况1,调用props.children,ComA 和 ComB不会重新渲染;
情况2,直接在App组件中的render函数内嵌ComA和ComB,会引发重新渲染;

情况1

ComA 和 ComB在App的render函数中是以props.children的形式体现出来的。这个props是App的props,而App渲染时,其props并未变化,相应的props.children,它是ComA 和 ComB的jsx形式,也没有变化,也就是说ComA 和 ComB的props同样没有变化,所以不会重新渲染。

情况2

ComA 和 ComB的形式在App的render函数中是<ComA />、<ComB />这最终会被编译成

React.createElement(ComA,?null)
React.createElement(ComB,?null)

它们执行后返回的时包含<ComA />和<ComB />props的一个对象(ReactElement)

export function createElement(type, config, children) {
  // 重点在这里,重新声明了props属性的引用
  const props = {};
  ...
  return ReactElement(
    type,
    key,
    ref,
    self,
    source,
    ReactCurrentOwner.current,
    props,
 );
}

也就是说,返回结果是一个ReactElement全新的引用,而它里面的props也是一个全新的对象,这也就意味着<ComA />和<ComB />的props变了,所以它们会重新渲染。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...