父传子

  1. let Child = (props) => {
  2. console.log("child render");
  3. return (
  4. <div></div>
  5. );
  6. };
  7. const App = () => {
  8. console.log("father render");
  9. const [count, setCount] = useState(0);
  10. const handleClick = () => {
  11. setCount((prev) => prev + 1);
  12. };
  13. return (
  14. <>
  15. {"父组件"}
  16. <div>
  17. {count}
  18. <button onClick={handleClick}>开始</button>
  19. </div>
  20. {"子组件"}
  21. <Child></Child>
  22. </>
  23. );
  24. };
  25. export default App;

点击按钮子组件 render ,并引起子组件render
image.png
下面这段代码我们点击子组件内部的按钮

  1. let Child = () => {
  2. const [count, setCount] = useState(0);
  3. const handleClick = () => {
  4. setCount((prev) => prev + 1);
  5. };
  6. console.log("child render");
  7. return (
  8. <div>
  9. {count}
  10. <button onClick={handleClick}>开始</button>
  11. </div>
  12. );
  13. };
  14. const App = () => {
  15. console.log("father render");
  16. const [count, setCount] = useState(0);
  17. const handleClick = () => {
  18. setCount((prev) => prev + 1);
  19. };
  20. return (
  21. <>
  22. {"父组件"}
  23. <div>
  24. {count}
  25. <button onClick={handleClick}>开始</button>
  26. </div>
  27. {"子组件"}
  28. <Child></Child>
  29. </>
  30. );
  31. };
  32. export default App;

打印结果:
image.png
可以看出子组件render并不影响父组件。

使用 memo 进行优化

memo 可以进行进行组件的浅比较,与之前 class 组件中的 PureComponents 功能相同。

  1. import React, { useState, memo } from "react";
  2. const Child = memo((props: any) => {
  3. console.log("child render");
  4. return <div>{props.count}</div>;
  5. });
  6. const App = () => {
  7. console.log("fahter render");
  8. const [count, setCount] = useState(0);
  9. const [count1, setCount1] = useState(3);
  10. const handleClick = () => {
  11. setCount((prev) => prev + 1);
  12. };
  13. return (
  14. <>
  15. {"父组件"}
  16. <div>
  17. {count}
  18. <button onClick={handleClick}>开始</button>
  19. </div>
  20. {"子组件"}
  21. <Child count={count1} />
  22. </>
  23. );
  24. };
  25. export default App;

打印结果:
image.png
通过对比 props 来选中是否进行更新。

当 props 中有 children 的时候

  1. import React, { useState, memo } from "react";
  2. const Child = memo((props: any) => {
  3. console.log("child render");
  4. return <div>{props.count.name}</div>;
  5. });
  6. const App = () => {
  7. console.log("fahter render");
  8. const [count, setCount] = useState(0);
  9. const [count1, setCount1] = useState({
  10. name: "chris",
  11. });
  12. const handleClick = () => {
  13. setCount((prev) => prev + 1);
  14. };
  15. return (
  16. <>
  17. {"父组件"}
  18. <div>
  19. {count}
  20. <button onClick={handleClick}>开始</button>
  21. </div>
  22. {"子组件"}
  23. <Child count={count1}>
  24. <div>1</div>
  25. </Child>
  26. </>
  27. );
  28. };
  29. export default App;

打印结果如下:
image.png
props中带有 children 或者传入一个 reactnode 时不会进行浅比较,会重新渲染组件。

总结

1.父组件更新,子组件会更新(可以使用memo进行优化,对props进行浅比较,防止子组件频繁更新)。

2.子组件内部更新,父组件不会更新(如果子组件调用父组件方法,依旧会更新)。

3.memo 关注于 props,mobx 的 obsersver 关注于 store 内状态。

4.props 中有 children(传入值为 reactnode)时,memo无效。